{"record":{"id":"dc743523d62a57a4","repo":"caddyserver/caddy","slug":"failed-to-load-system-cert-pool-v","errorCode":null,"errorMessage":"failed to load system cert pool: %v","messagePattern":"failed to load system cert pool: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/capools.go","lineNumber":802,"sourceCode":"type SystemCAPool struct {\n\tpool *x509.CertPool\n}\n\n// CaddyModule implements caddy.Module.\nfunc (SystemCAPool) CaddyModule() caddy.ModuleInfo {\n\treturn caddy.ModuleInfo{\n\t\tID: \"tls.ca_pool.source.system\",\n\t\tNew: func() caddy.Module {\n\t\t\treturn new(SystemCAPool)\n\t\t},\n\t}\n}\n\n// Provision implements caddy.Provisioner.\nfunc (scp *SystemCAPool) Provision(ctx caddy.Context) error {\n\tpool, err := x509.SystemCertPool()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to load system cert pool: %v\", err)\n\t}\n\tscp.pool = pool\n\treturn nil\n}\n\nfunc (scp *SystemCAPool) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {\n\td.Next() // consume module name\n\tif d.CountRemainingArgs() > 0 {\n\t\treturn d.ArgErr()\n\t}\n\tif d.NextBlock(0) {\n\t\treturn d.Err(\"system trust pool does not support any configuration\")\n\t}\n\treturn nil\n}\n\n// CertPool implements CA.\nfunc (scp SystemCAPool) CertPool() *x509.CertPool {","sourceCodeStart":784,"sourceCodeEnd":820,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/capools.go#L784-L820","documentation":"The `tls.ca_pool.source.system` pool calls x509.SystemCertPool() to load the OS trust store, and that call failed. On most platforms this only fails when the system certificate store cannot be read or parsed at all.","triggerScenarios":"The OS trust store is missing, empty, unreadable, or corrupt — e.g. a minimal container with no ca-certificates package, a broken /etc/ssl/certs, or unusual permissions on the trust store files.","commonSituations":"Docker/Distroless/scratch images without ca-certificates installed; chroots with incomplete /etc/ssl; broken symlinks in the cert directory after a partial update.","solutions":["In containers, install the CA certificates package (e.g. `apt-get install -ca-certificates` on Debian, `apk add ca-certificates` on Alpine) and rebuild.","On hosts, rebuild the trust store (Debian: `update-ca-certificates --fresh`; RHEL: `update-ca-trust`).","If the system store genuinely cannot be fixed, use an explicit `file` or `inline` trust pool instead of `system`."],"exampleFix":"# before: Dockerfile\nFROM scratch\nCOPY caddy /caddy\n\n# after: Dockerfile\nFROM alpine:3.20\nRUN apk add --no-cache ca-certificates\nCOPY caddy /usr/bin/caddy","handlingStrategy":"validation","validationCode":"// container/CI check: system store readable and non-empty (unix)\nimport (\n\t\"crypto/x509\"\n\t\"os\"\n)\n\nfunc systemStoreOK() error {\n\tif _, err := x509.SystemCertPool(); err != nil {\n\t\treturn fmt.Errorf(\"system cert pool unavailable: %w\", err)\n\t}\n\tif _, err := os.Stat(\"/etc/ssl/certs\"); os.IsNotExist(err) {\n\t\treturn errors.New(\"no /etc/ssl/certs; install ca-certificates\")\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Base containers on images that include ca-certificates, or install it in the Dockerfile.","Add a startup health check that loads the system pool before Caddy serves traffic.","For immutable/minimal images, prefer explicit `file` trust pools over `system`."],"tags":["caddy","caddytls","system","trust-store","container"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}