{"record":{"id":"be32f83641bd25b2","repo":"JuliusBrussee/caveman","slug":"load-system-certificate-pool-w","errorCode":null,"errorMessage":"load system certificate pool: %w","messagePattern":"load system certificate pool: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/cabundle/cabundle.go","lineNumber":34,"sourceCode":"// private CA is trusted for the inspected ones. Any unusable bundle fails the\n// whole pool CLOSED; see Certificates.\nfunc Pool(paths ...string) (*x509.CertPool, error) {\n\tvar certs []*x509.Certificate\n\tfor _, path := range paths {\n\t\tloaded, err := Certificates(path)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcerts = append(certs, loaded...)\n\t}\n\treturn PoolOf(certs)\n}\n\n// PoolOf returns the system pool with certs appended.\nfunc PoolOf(certs []*x509.Certificate) (*x509.CertPool, error) {\n\troots, err := x509.SystemCertPool()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"load system certificate pool: %w\", err)\n\t}\n\tfor _, cert := range certs {\n\t\troots.AddCert(cert)\n\t}\n\treturn roots, nil\n}\n\n// Certificates parses every certificate in the PEM bundle at path.\n//\n// The bundle is parsed block by block instead of via CertPool.AppendCertsFromPEM,\n// which reports success as soon as ONE certificate parses and silently drops the\n// rest. A truncated or corrupt bundle would then be half-trusted: the endpoints\n// whose issuer survived keep verifying and the ones whose issuer was dropped fail\n// later, looking like a network fault. Any unusable certificate block — or a\n// trailing PEM header with no complete block behind it — rejects the whole\n// bundle instead, and nothing from it is returned.\nfunc Certificates(path string) ([]*x509.Certificate, error) {\n\tbundle, err := os.ReadFile(path)","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/cabundle/cabundle.go#L16-L52","documentation":"PoolOf starts from the operating system's root certificate pool via x509.SystemCertPool() and appends custom certificates. If the system pool cannot be loaded (platform-level failure reading the OS trust store), the error is wrapped with this message. The library throws it because it cannot establish a trust baseline without the system roots.","triggerScenarios":"Calling PoolOf (directly or through Pool/loadRootCAs) on a system where x509.SystemCertPool() fails: missing /etc/ssl/certs on minimal Linux images, an unreadable or corrupt CA bundle path (SSL_CERT_FILE/SSL_CERT_DIR pointing nowhere), or unsupported platforms (notably some Windows/older Go versions returned an error for SystemCertPool).","commonSituations":"Scratch/distroless containers without ca-certificates installed; SSL_CERT_FILE set to a nonexistent path; alpine images lacking the ca-certificates package; statically linked builds on platforms without a discoverable trust store.","solutions":["Install the CA certificates: on Debian/Ubuntu `apt-get install -y ca-certificates`, on Alpine `apk add ca-certificates`, on RHEL `yum install ca-certificates`.","Check SSL_CERT_FILE/SSL_CERT_DIR env vars point to existing, readable files/directories and unset them if wrong.","If the platform truly has no system pool, load a bundled PEM file via cabundle.Certificates and pass it to PoolOf — or use x509.NewCertPool() seeded from a known-good bundle.","Upgrade Go if on an old version where SystemCertPool errored on Windows."],"exampleFix":"// Dockerfile (before)\nFROM golang:1.22 AS build\nFROM scratch\n// after\nFROM golang:1.22 AS build\nFROM scratch\nCOPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/","handlingStrategy":"fallback","validationCode":"if _, err := x509.SystemCertPool(); err != nil {\n    // fall back to a bundled CA file before calling PoolOf\n    certs, cerr := cabundle.Certificates(\"/app/certs/ca-bundle.pem\")\n    if cerr != nil { return cerr }\n    pool := x509.NewCertPool()\n    for _, c := range certs { pool.AddCert(c) }\n}","typeGuard":null,"tryCatchPattern":"pool, err := cabundle.PoolOf(extra)\nif err != nil && strings.Contains(err.Error(), \"load system certificate pool\") {\n    return fmt.Errorf(\"OS trust store unavailable (install ca-certificates or set SSL_CERT_FILE): %w\", err)\n}","preventionTips":["Install ca-certificates in every container image, including scratch/distroless builds (copy /etc/ssl/certs).","Do not set SSL_CERT_FILE/SSL_CERT_DIR to nonexistent paths.","Ship a known-good fallback CA bundle for environments without a system store."],"tags":["tls","certificates","x509","environment"],"backgroundTag":"missing-dependency","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}