{"record":{"id":"3355a67d14070ee8","repo":"caddyserver/caddy","slug":"could-not-parse-leaf-certificates-loaders-s","errorCode":null,"errorMessage":"could not parse leaf certificates loaders: %s","messagePattern":"could not parse leaf certificates loaders: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/connpolicy.go","lineNumber":971,"sourceCode":"\tLeafCertificateLoadersRaw []json.RawMessage `json:\"leaf_certs_loaders,omitempty\" caddy:\"namespace=tls.leaf_cert_loader inline_key=loader\"`\n\ttrustedLeafCerts          []*x509.Certificate\n}\n\n// CaddyModule returns the Caddy module information.\nfunc (LeafCertClientAuth) CaddyModule() caddy.ModuleInfo {\n\treturn caddy.ModuleInfo{\n\t\tID:  \"tls.client_auth.verifier.leaf\",\n\t\tNew: func() caddy.Module { return new(LeafCertClientAuth) },\n\t}\n}\n\nfunc (l *LeafCertClientAuth) Provision(ctx caddy.Context) error {\n\tif l.LeafCertificateLoadersRaw == nil {\n\t\treturn nil\n\t}\n\tval, err := ctx.LoadModule(l, \"LeafCertificateLoadersRaw\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not parse leaf certificates loaders: %s\", err.Error())\n\t}\n\ttrustedLeafCertloaders := []LeafCertificateLoader{}\n\tfor _, loader := range val.([]any) {\n\t\ttrustedLeafCertloaders = append(trustedLeafCertloaders, loader.(LeafCertificateLoader))\n\t}\n\ttrustedLeafCertificates := []*x509.Certificate{}\n\tfor _, loader := range trustedLeafCertloaders {\n\t\tcerts, err := loader.LoadLeafCertificates()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"could not load leaf certificates: %s\", err.Error())\n\t\t}\n\t\ttrustedLeafCertificates = append(trustedLeafCertificates, certs...)\n\t}\n\tl.trustedLeafCerts = trustedLeafCertificates\n\treturn nil\n}\n\n// UnmarshalCaddyfile implements caddyfile.Unmarshaler.","sourceCodeStart":953,"sourceCodeEnd":989,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/connpolicy.go#L953-L989","documentation":"LeafCertClientAuth.Provision loads the raw modules under LeafCertificateLoadersRaw (the 'leaf certificate loaders' of the tls.client_auth.verifier.leaf module); if any fails to load or instantiate, the error is wrapped as 'could not parse leaf certificates loaders'. This is a config/module-loading failure, before any file is read.","triggerScenarios":"Specifying verifier leaf { leaf_cert <name> { ... } } in a Caddyfile or the equivalent JSON where the loader module name is unknown or its body is malformed; a third-party loader module that fails its own Provision/Validate.","commonSituations":"Typos in the loader module name (e.g. 'file ' vs 'file', 'inline' misspelled); JSON hand-written with a wrong 'loader' key value; XCaddy plugin loaders missing from the build so the module ID is unresolvable.","solutions":["Check the loader module name and block syntax against the docs: 'inline' (leaf_cert inline <base64 der>) and 'file' (leaf_cert file <path>) are the stock loaders","For JSON, ensure each entry is a module object with \"loader\": \"inline\" or \"loader\": \"file\"","If a custom loader is referenced, confirm it is compiled in: caddy list-modules | grep tls.leaf_cert_loader","Run caddy validate to get the underlying wrapped error detail"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// (shell) confirm loader modules exist before referencing them\ncaddy list-modules | grep '^tls\\.leaf_cert_loader\\.'\n# expect: tls.leaf_cert_loader.file, tls.leaf_cert_loader.inline","typeGuard":"// For custom loaders: prove interface compliance at compile time\nvar _ caddytls.LeafCertificateLoader = (*MyLoader)(nil)","tryCatchPattern":"if err := caddy.Run(cfg); err != nil {\n\tif strings.Contains(err.Error(), \"could not parse leaf certificates loaders\") {\n\t\t// inspect inner error: usually unknown module name or bad loader body\n\t\tlog.Printf(\"leaf loader config error: %v\", err)\n\t}\n}","preventionTips":["Use Caddyfile form (verifier leaf { leaf_cert file ... }) instead of hand-written JSON where possible","Run caddy validate after changing any client_auth verifier stanza","Rebuild custom loaders with the same xcaddy build as the target Caddy version"],"tags":["tls","client-auth","module-system","config"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}