{"record":{"id":"81d6fb1f452e598b","repo":"caddyserver/caddy","slug":"expanding-dns-override-domain-s-v","errorCode":null,"errorMessage":"expanding DNS override domain '%s': %v","messagePattern":"expanding DNS override domain '(.+?)': (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/acmeissuer.go","lineNumber":192,"sourceCode":"\t\t\t}\n\t\t\tiss.ExternalAccount.MACKey = macKey\n\t\t}\n\t}\n\n\t// expand account key, if non-empty\n\tif iss.AccountKey != \"\" {\n\t\taccountKey, err := repl.ReplaceOrErr(iss.AccountKey, true, true)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"expanding account key PEM '%s': %v\", iss.AccountKey, err)\n\t\t}\n\t\tiss.AccountKey = accountKey\n\t}\n\n\t// expand DNS override domain, if non-empty\n\tif iss.Challenges != nil && iss.Challenges.DNS != nil && iss.Challenges.DNS.OverrideDomain != \"\" {\n\t\toverrideDomain, err := repl.ReplaceOrErr(iss.Challenges.DNS.OverrideDomain, true, true)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"expanding DNS override domain '%s': %v\", iss.Challenges.DNS.OverrideDomain, err)\n\t\t}\n\t\tiss.Challenges.DNS.OverrideDomain = overrideDomain\n\t}\n\n\t// DNS challenge provider, if not already established\n\tif iss.Challenges != nil && iss.Challenges.DNS != nil && iss.Challenges.DNS.solver == nil {\n\t\tvar prov certmagic.DNSProvider\n\t\tif iss.Challenges.DNS.ProviderRaw != nil {\n\t\t\t// a challenge provider has been locally configured - use it\n\t\t\tval, err := ctx.LoadModule(iss.Challenges.DNS, \"ProviderRaw\")\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"loading DNS provider module: %v\", err)\n\t\t\t}\n\t\t\tprov = val.(certmagic.DNSProvider)\n\t\t} else if tlsAppIface, err := ctx.AppIfConfigured(\"tls\"); err == nil {\n\t\t\t// no locally configured DNS challenge provider, but if there is\n\t\t\t// a global DNS module configured with the TLS app, use that\n\t\t\ttlsApp := tlsAppIface.(*TLS)","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/acmeissuer.go#L174-L210","documentation":"Returned by ACMEIssuer.Provision (modules/caddytls/acmeissuer.go:192) when the DNS-01 challenge override domain (DNS override_domain, JSON \"override_domain\") contains a placeholder that fails expansion - unknown env var or malformed placeholder. This option redirects challenge DNS records to a different zone (e.g. when using a DNS provider that only manages a parent domain), and provisioning stops if its value cannot be resolved.","triggerScenarios":"Configuring challenges { dns { override_domain {env.DNS_ZONE} } } where DNS_ZONE is not set in Caddy's environment, or the placeholder has a typo/broken braces.","commonSituations":"Wildcard cert setups (*.example.com) using override_domain to answer in example.com; the env var exists in dev but not in the deployed unit; variable renamed when the DNS setup moved to another provider.","solutions":["Export DNS_ZONE in the service environment and restart Caddy","Or write the literal zone name: override_domain example.com","Fix placeholder syntax to exactly {env.DNS_ZONE}","Validate the whole config with caddy validate before deploy"],"exampleFix":"# before\n *.example.com {\n   tls {\n     dns cloudflare {env.CF_TOKEN} {\n       override_domain {env.DNS_OVR}   # unset\n     }\n   }\n }\n\n# after\n *.example.com {\n   tls {\n     dns cloudflare {env.CF_TOKEN} {\n       override_domain example.com\n     }\n   }\n }","handlingStrategy":"validation","validationCode":"if strings.Contains(cfgText, \"{env.DNS_ZONE}\") && os.Getenv(\"DNS_ZONE\") == \"\" {\n    return errors.New(\"DNS_ZONE referenced by override_domain but not set\")\n}","typeGuard":null,"tryCatchPattern":"if err := issuer.Provision(ctx); err != nil {\n    if strings.Contains(err.Error(), \"expanding DNS override domain\") {\n        // replace with the literal parent zone or set the env var\n    }\n    return err\n}","preventionTips":["Override zones are stable per-domain: prefer literals over placeholders","Keep DNS challenge options in a shared snippet reviewed together with the DNS provider creds","Add placeholder-vs-env consistency checks to config CI"],"tags":["tls","acme","dns-challenge","placeholders","wildcard"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}