{"record":{"id":"8c317ea4e9f67d8c","repo":"thanos-io/thanos","slug":"reading-system-certificate-pool","errorCode":null,"errorMessage":"reading system certificate pool","messagePattern":"reading system certificate pool","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/tls/options.go","lineNumber":150,"sourceCode":"// minTLSVersion must be one of 1.0, 1.1, 1.2, 1.3 per GetTlsVersion().\nfunc NewClientConfig(logger log.Logger, cert, key, caCert, serverName string, skipVerify bool, minTLSVersion string) (*tls.Config, error) {\n\tvar certPool *x509.CertPool\n\tif caCert != \"\" {\n\t\tcaPEM, err := os.ReadFile(filepath.Clean(caCert))\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"reading client CA\")\n\t\t}\n\n\t\tcertPool = x509.NewCertPool()\n\t\tif !certPool.AppendCertsFromPEM(caPEM) {\n\t\t\treturn nil, errors.Wrap(err, \"building client CA\")\n\t\t}\n\t\tlevel.Debug(logger).Log(\"msg\", \"TLS client using provided certificate pool\")\n\t} else {\n\t\tvar err error\n\t\tcertPool, err = x509.SystemCertPool()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"reading system certificate pool\")\n\t\t}\n\t\tlevel.Debug(logger).Log(\"msg\", \"TLS client using system certificate pool\")\n\t}\n\n\tvar (\n\t\tmtlsVersion uint16\n\t\terr         error\n\t)\n\n\tif minTLSVersion != \"\" {\n\t\tmtlsVersion, err = GetTlsVersion(minTLSVersion)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlevel.Debug(logger).Log(\"msg\", fmt.Sprintf(\"setting minimum TLS version to %s\", minTLSVersion))\n\t}\n\ttlsCfg := &tls.Config{\n\t\tRootCAs:    certPool,","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/tls/options.go#L132-L168","documentation":"NewClientConfig wraps this error when no custom caCert is given and x509.SystemCertPool() fails to load the operating system's trusted root certificate pool. This typically means no system CA store is available or readable.","triggerScenarios":"NewClientConfig called with empty caCert on a system without the expected CA bundle (e.g. a scratch/alpine/distroless container lacking /etc/ssl/certs or ca-certificates package).","commonSituations":"Minimal Docker images without ca-certificates installed; running on Windows with restricted crypto API; SSL_CERT_FILE/SSL_CERT_DIR pointing at nonexistent paths (Go 1.18+ returns error).","solutions":["Install system CA certs: apt-get install -y ca-certificates or apk add ca-certificates.","Use a distroless/base image variant that includes CA certificates.","Explicitly provide caCert path to NewClientConfig instead of relying on the system pool.","Unset/fix SSL_CERT_FILE / SSL_CERT_DIR if they point to missing locations."],"exampleFix":"# before\nFROM scratch\nCOPY app /app\n# after\nFROM gcr.io/distroless/static:latest\nCOPY app /app","handlingStrategy":"try-catch","validationCode":"if caCert == \"\" {\n    if _, err := x509.SystemCertPool(); err != nil {\n        return fmt.Errorf(\"no system CA pool: %w; install ca-certificates or set caCert\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"cfg, err := tls.NewClientConfig(logger, cert, key, \"\", serverName, skipVerify, ver)\nif err != nil && strings.Contains(err.Error(), \"reading system certificate pool\") {\n    // fall back to an explicitly provided CA bundle\n    cfg, err = tls.NewClientConfig(logger, cert, key, \"/etc/ssl/certs/ca-certificates.crt\", serverName, skipVerify, ver)\n}","preventionTips":["Include ca-certificates in container images.","Use distroless/static image variants with bundled CAs.","Prefer passing an explicit CA file in minimal environments.","Don't set SSL_CERT_FILE/SSL_CERT_DIR to nonexistent paths."],"tags":["tls","x509","system","certificates"],"backgroundTag":"missing-dependency","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}