oauth2-proxy/oauth2-proxy · error
SystemCertPool is empty
Error message
SystemCertPool is empty
What it means
getSystemCertPool wraps x509.SystemCertPool() and returns this error when Go's certificate pool comes back nil instead of a usable (possibly empty) pool. On some platforms (notably older Go versions on Windows or stripped-down Linux images) the system root store cannot be loaded, yielding a nil pool. The library refuses to continue building a TLS trust pool from nothing.
Source
Thrown at pkg/util/util.go:47
return nil, fmt.Errorf("unable to get SystemCertPool when append is true - #{err}")
}
pool = rootPool
} else {
pool = x509.NewCertPool()
}
return loadCertsFromPaths(paths, pool)
}
func getSystemCertPool() (*x509.CertPool, error) {
rootPool, err := x509.SystemCertPool()
if err != nil {
return nil, err
}
if rootPool == nil {
return nil, fmt.Errorf("SystemCertPool is empty")
}
return rootPool, nil
}
func loadCertsFromPaths(paths []string, pool *x509.CertPool) (*x509.CertPool, error) {
for _, path := range paths {
// Cert paths are a configurable option
data, err := os.ReadFile(path) // #nosec G304
if err != nil {
return nil, fmt.Errorf("certificate authority file (%s) could not be read - %s", path, err)
}
if !pool.AppendCertsFromPEM(data) {
return nil, fmt.Errorf("loading certificate authority (%s) failed", path)
}
}
return pool, nil
}View on GitHub (pinned to 33c2eb92de)
Solutions
- Install system CA certificates (e.g. apt-get install ca-certificates or apk add ca-certificates) so the system trust store exists
- Upgrade Go to a recent version where x509.SystemCertPool reliably returns a non-nil pool
- Pass explicit CA file paths via the cert pool path configuration so pool construction does not depend on the system store
- Check the underlying x509 error returned before this message for the real platform cause
Example fix
// before
rootPool, err := x509.SystemCertPool()
if err != nil {
return nil, err
}
// after (fallback to an empty pool and load explicit CAs)
rootPool, err := x509.SystemCertPool()
if err != nil || rootPool == nil {
rootPool = x509.NewCertPool()
} Defensive patterns
Strategy: validation
Validate before calling
if _, err := x509.SystemCertPool(); err != nil || rootPoolNil() { /* install CA certs before starting */ }
func rootPoolNil() bool { p, _ := x509.SystemCertPool(); return p == nil } Type guard
func systemPoolAvailable() bool { p, _ := x509.SystemCertPool(); return p != nil } Prevention
- Install ca-certificates in container images
- Pin a recent Go version
- Configure explicit CA file paths as a fallback
When it happens
Trigger: GetCertPool -> getSystemCertPool when x509.SystemCertPool() returns (nil, nil), which happens on platforms where the system cert store is unavailable or on Go versions with platform-specific cert-loading bugs.
Common situations: Running in a minimal/alpine or scratch Docker image without ca-certificates installed; Windows or macOS with an empty/unreadable system trust store; older Go runtimes with known x509 SystemCertPool bugs.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- certificate authority file (%s) could not be read - %s
- loading certificate authority (%s) failed
- error setting up TLS listener: %v
- unknown TLS cipher suite name specified %q
- could not load certificate: %v
AI-assisted analysis of oauth2-proxy/oauth2-proxy@33c2eb92de (2026-09-06).
Data as JSON: /api/errors/20664ce0164c58cc.
Report an issue: GitHub.