{"record":{"id":"8492193b50dc70d8","repo":"caddyserver/caddy","slug":"loading-ech-dns-provider-module-v","errorCode":null,"errorMessage":"loading ECH DNS provider module: %v","messagePattern":"loading ECH DNS provider module: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/ech.go","lineNumber":798,"sourceCode":"\tProviderRaw json.RawMessage `json:\"provider,omitempty\" caddy:\"namespace=dns.providers inline_key=name\"`\n\tprovider    ECHDNSProvider\n\n\talpnByDomain map[string][]string\n\tlogger       *zap.Logger\n}\n\n// CaddyModule returns the Caddy module information.\nfunc (ECHDNSPublisher) CaddyModule() caddy.ModuleInfo {\n\treturn caddy.ModuleInfo{\n\t\tID:  \"tls.ech.publishers.dns\",\n\t\tNew: func() caddy.Module { return new(ECHDNSPublisher) },\n\t}\n}\n\nfunc (dnsPub *ECHDNSPublisher) Provision(ctx caddy.Context) error {\n\tdnsProvMod, err := ctx.LoadModule(dnsPub, \"ProviderRaw\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"loading ECH DNS provider module: %v\", err)\n\t}\n\tprov, ok := dnsProvMod.(ECHDNSProvider)\n\tif !ok {\n\t\treturn fmt.Errorf(\"ECH DNS provider module is not an ECH DNS Provider: %v\", err)\n\t}\n\tdnsPub.provider = prov\n\tdnsPub.logger = ctx.Logger()\n\treturn nil\n}\n\n// PublisherKey returns the name of the DNS provider module.\n// We intentionally omit specific provider configuration (or a hash thereof,\n// since the config is likely sensitive, potentially containing an API key)\n// because it is unlikely that specific configuration, such as an API key,\n// is relevant to unique key use as an ECH config publisher.\nfunc (dnsPub ECHDNSPublisher) PublisherKey() string {\n\treturn string(dnsPub.provider.(caddy.Module).CaddyModule().ID)\n}","sourceCodeStart":780,"sourceCodeEnd":816,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/ech.go#L780-L816","documentation":"The tls.ech.publishers.dns module (ECHDNSPublisher) embeds a pluggable DNS provider module loaded at provision time via ctx.LoadModule(dnsPub, \"ProviderRaw\"). This error wraps a module-load failure: the provider name in the config does not resolve to a registered module, or the provider module itself failed its own provisioning (bad credentials, invalid options). The message chains the underlying error.","triggerScenarios":"Config with tls.ech.publisher.dns whose provider is unknown (typo'd module name), a provider built without its build tag or not compiled into the binary, or a provider whose Provision rejects options (bad API token format, missing zone credentials).","commonSituations":"JSON config referencing a libdns provider that is not in the standard build; typo like \"providers\": {\"clouddns\": ...} vs actual module namespace; rotated/expired DNS provider API token causing the provider's own provisioning to fail; using a custom Caddy build that omitted the provider import.","solutions":["Read the wrapped (%v) cause — it usually names the exact module problem (unrecognized name or provider-specific provisioning error).","Fix the provider module name in config to match a registered tls DNS provider module.","Supply/refresh the provider credentials and options.","If the provider isn't in the build, use a Caddy build that includes it (xcaddy build with the libdns provider package imported)."],"exampleFix":"// before\n{\"provider\":{\"name\":\"cloudflaredns\",\"api_token\":\"...\"}}\n\n// after: match the registered module namespace\n{\"provider\":{\"name\":\"cloudflare\",\"api_token\":\"...\"}}","handlingStrategy":"validation","validationCode":"// Validate provider module name against registered modules before load.\nprov := cfg.Provider // caddy.Module etc.\nif prov.Name == \"\" || !knownECHDNSProvider(prov.Name) {\n    return fmt.Errorf(\"unknown ECH DNS provider: %q\", prov.Name)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"loading ECH DNS provider module\") {\n    // unwrap %v cause: unknown module name or provider provisioning failure\n    return fmt.Errorf(\"fix ECH DNS provider config: %w\", err)\n}","preventionTips":["Use provider module names exactly as registered (check caddy list-modules).","Keep provider credentials fresh; test them with the provider's CLI before deploy.","Build custom binaries with xcaddy including every provider referenced in config."],"tags":["tls","ech","dns","module-system","config"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}