1. The problem I’m having:
I have the following issue/scenario. We are using debian 11 and caddy as a reverse proxy server to manage an ERP system. We have 2 domains from our own company. then our customer can whitelabel. We use cloudflare as our entry point.
Our own domains are hosted by cloudflare, customer domain is hosted externally.
Via custom Hostnames under the SSL system of cloudflaire we configured DNS-01 config and when checking the dashboard from cloudlfare all settings seems correct, we use Strick until Origin Server.
Now the issue, after a reboot of the proxy server, the custom domains get an SSL handshake failed Error code 525.The config, as far as i know did not change, and before the reboot all was working fine?
When i check in the folder where the SSL certificates are storeed, i see all other SSL domains folders, but the custom certificate for login.parani.co.id is not created/ does not exist
Under login.vanlooveren.info all is working but under login.parani.co.id it fails
Note vanlooveren.info is registred under cloudflair, parani.co.id is not.
2. Error messages and/or full log output:
```
2025/08/18 11:21:35.097 e\[31mERRORe\[0m tls.obtain could not get certificate from issuer {“identifier”: “login.parani.co.id”, “issuer”: “acme-v02.api.letsencrypt.org-directory”, “error”: “\[login.parani.co.id\] solving challenges: presenting for challenge: adding temporary record for zone "parani.co.id.": expected 1 zone, got 0 for parani.co.id. (order=https://acme-staging-v02.api.letsencrypt.org/acme/order/153406413/26722229634) (ca=https://acme-staging-v02.api.letsencrypt.org/directory)”}
2025/08/18 11:21:35.097 e\[31mERRORe\[0m tls.obtain will retry {“error”: “\[login.parani.co.id\] Obtain: \[login.parani.co.id\] solving challenges: presenting for challenge: adding temporary record for zone "parani.co.id.": expected 1 zone, got 0 for parani.co.id. (order=https://acme-staging-v02.api.letsencrypt.org/acme/order/153406413/26722229634) (ca=https://acme-staging-v02.api.letsencrypt.org/directory)”, “attempt”: 12, “retrying_in”: 1800, “elapsed”: 7224.255537743, “max_duration”: 2592000}
2025/08/18 11:21:35.097 e[31mERRORe[0m cleaning up solver {"identifier": "login.parani.co.id", "challenge_type": "dns-01", "error": "no memory of presenting a DNS record for \"_acme-challenge.login.parani.co.id\" (usually OK if presenting also failed)"}
github.com/mholt/acmez/v3.(*Client).solveChallenges.func1
github.com/mholt/acmez/v3@v3.1.2/client.go:318
github.com/mholt/acmez/v3.(*Client).solveChallenges
github.com/mholt/acmez/v3@v3.1.2/client.go:363
github.com/mholt/acmez/v3.(*Client).ObtainCertificate
github.com/mholt/acmez/v3@v3.1.2/client.go:136
github.com/caddyserver/certmagic.(*ACMEIssuer).doIssue
github.com/caddyserver/certmagic@v0.23.0/acmeissuer.go:489
github.com/caddyserver/certmagic.(*ACMEIssuer).Issue
github.com/caddyserver/certmagic@v0.23.0/acmeissuer.go:382
github.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue
github.com/caddyserver/caddy/v2@v2.10.0/modules/caddytls/acmeissuer.go:288
github.com/caddyserver/certmagic.(*Config).obtainCert.func2
github.com/caddyserver/certmagic@v0.23.0/config.go:626
github.com/caddyserver/certmagic.doWithRetry
github.com/caddyserver/certmagic@v0.23.0/async.go:104
github.com/caddyserver/certmagic.(*Config).obtainCert
github.com/caddyserver/certmagic@v0.23.0/config.go:700
github.com/caddyserver/certmagic.(*Config).ObtainCertAsync
github.com/caddyserver/certmagic@v0.23.0/config.go:505
github.com/caddyserver/certmagic.(*Config).manageOne.func1
github.com/caddyserver/certmagic@v0.23.0/config.go:415
github.com/caddyserver/certmagic.(*jobManager).worker
github.com/caddyserver/certmagic@v0.23.0/async.go:73
```
3. Caddy version:
I am using caddy version 2.10.0 but with the cloudflare module.
4. How I installed and ran Caddy:
caddy is running on a Debian VM with only caddy installed, as we use caddy here only as a reverse proxy.
a. System environment:
Debian GNU/Linux 11 (bullseye) x68, no docker, downloaded the caddy module via website, then uploaded it via ssh to debian server.
b. Command:
systemctl stop caddy
cd /usr/bin/
mv /usr/bin/caddy /usr/bin/caddyold
mv /usr/bin/caddy_linux_amd64_custom /usr/bin/caddy
chmod +x /usr/bin/caddy
systemctl start caddy
c. Service/unit/compose file:
we do not use docker, plain debian with caddy only, no other software, pure proxy server
d. My complete Caddy config:
```
{
debug
email ssl@optilog.solutions
metrics {
per_host
}
admin localhost:2019
log {
level WARN
output file /var/log/caddy/caddy.log
format console
}
}
(tlsCloudFlare) {
tls {
dns cloudflare
resolvers 1.1.1.1
propagation_timeout 5m
}
}
(tlsOffloadHandle) {
# Do Not Offload the ssl cert here, but pass-through until the next Server.
transport http {
tls_server_name {host}
tls
tls_insecure_skip_verify
}
}
(cacheable) {
@cacheable {
path *.css *.jpg *.jpeg *.png *.gif *.webp *.svg
not header Cache-Control *no-cache*
}
header @cacheable Cache-Control "max-age=31536000"
}
(emptyUserAgentHeader) {
# Filter out empty or missing user agent strings.
@blankUserAgent {
not header User-Agent * # Matches requests where the User-Agent header is empty or missing
}
respond @blankUserAgent 403
}
(botUserAgentHeader) {
# filter out all the bot systems.
@botUserAgent {
header_regexp User-Agent "(bot|Googlebot)"
}
respond @botUserAgent 403
}
(garbageFilter) {
# Prevent access to dot-files, except .well-known
@dotFiles {
path */.*
path /wp-admin
path /wp-content
path /admin
path /server
path /assets
path /debug
path /default
path /js
path /core
not path /.well-known/*
}
respond @dotFiles 403
}
(erpFilter) {
redir / /login/Login 302
# White list of accepted controller.
@erpController {
# White list of accepted controller.
not path /favicon.ico
not path /manifest.webmanifest
not path /robots.txt
path /info.php
path /index.php
path */*
}
respond @erpController 403
}
(proxyHeader) {
## Extra Header Configs that defaults to all servers
header {
>Server "Caddy" "optiLogProxyServers"
?Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
?X-Frame-Options "DENY"
?X-Content-Type-Options nosniff
?Referrer-Policy strict-origin-when-cross-origin
?Permissions-Policy "camera=(self), geolocation=(self)"
}
}
# Import external Configuration files.
import frontend.caddy
import backend.caddy
# Production allowed customers domains.
https://login.parani.co.id {
import tlsCloudFlare
reverse_proxy https://erp.internal:5698 {
import tlsOffloadHandle
}
import erpFilter
import garbageFilter
import emptyUserAgentHeader
import botUserAgentHeader
import proxyHeader
import cacheable
}
# Personal test domains
https://login.vanlooveren.info {
import tlsCloudFlare
reverse_proxy https://erp.internal:5698 {
import tlsOffloadHandle
}
import erpFilter
import garbageFilter
import emptyUserAgentHeader
import botUserAgentHeader
import proxyHeader
import cacheable
}
# Main server configuration - properly configured for HTTPS
:443 {
tls {
dns cloudflare
resolvers 1.1.1.1
propagation_timeout 5m
}
respond "Access Denied" 403
}
# HTTP to HTTPS redirect
:80 {
redir https://{host}{uri} 301
}
```