{"record":{"id":"b941137c34763447","repo":"caddyserver/caddy","slug":"could-not-load-leaf-certificates-s","errorCode":null,"errorMessage":"could not load leaf certificates: %s","messagePattern":"could not load leaf certificates: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/connpolicy.go","lineNumber":981,"sourceCode":"}\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.\nfunc (l *LeafCertClientAuth) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {\n\td.NextArg()\n\n\t// accommodate the use of one-liners\n\tif d.CountRemainingArgs() > 1 {\n\t\td.NextArg()\n\t\tmodName := d.Val()\n\t\tmod, err := caddyfile.UnmarshalModule(d, \"tls.leaf_cert_loader.\"+modName)\n\t\tif err != nil {\n\t\t\treturn d.WrapErr(err)","sourceCodeStart":963,"sourceCodeEnd":999,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/connpolicy.go#L963-L999","documentation":"After successfully parsing leaf cert loaders, LeafCertClientAuth.Provision calls LoadLeafCertificates() on each; any failure (missing file, unreadable file, bad base64 in inline loader) is wrapped as 'could not load leaf certificates'. The load itself failed, as opposed to module parsing (previous error).","triggerScenarios":"leaf_cert_file pointing to a nonexistent path or a path the Caddy process cannot read; leaf_cert inline with base64 that does not decode to a certificate; file containing something other than certificate PEM/DER depending on loader implementation.","commonSituations":"Container deployments where the cert file is not mounted into the container; file permissions (root-owned file, Caddy running as non-root); deploying config before provisioning certs; path typos or missing directory.","solutions":["Verify the path exists and is readable by the Caddy user: ls -l /etc/caddy/leaf.pem and run with the service user","Fix container mounts/volumes so the cert file is present at the configured path","For the inline loader, re-encode the cert: base64 -w0 leaf.der and paste the full string","Check the underlying error text after the colon — it states file or decode specifics"],"exampleFix":"# before\nverifier leaf {\n  leaf_cert_file /etc/caddy/leaf.pem\n}\n\n# after (ensure the file exists; or inline it)\nverifier leaf {\n  leaf_cert inline MIIB...==\n}","handlingStrategy":"validation","validationCode":"// Pre-flight every file referenced by leaf_cert_file\nfunc checkLeafCertFiles(paths ...string) error {\n\tfor _, p := range paths {\n\t\tb, err := os.ReadFile(p)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"leaf cert %s: %w\", p, err)\n\t\t}\n\t\tif _, rest := pem.Decode(b); rest == nil && len(b) > 0 {\n\t\t\tif _, err := x509.ParseCertificate(b); err != nil {\n\t\t\t\treturn fmt.Errorf(\"leaf cert %s: not PEM or DER cert\", p)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Mount cert files read-only into containers and health-check their presence in entrypoint","Set explicit file ownership for the caddy service user","Smoke-test with 'caddy validate' plus an mTLS request after every deploy"],"tags":["tls","client-auth","file-io","containers"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}