JuliusBrussee/caveman · error
postgres: set only or , not both
Error message
postgres: set only %s or %s, not both
What it means
caPEMFromEnvironment reads the CA either from a file path env var or from a direct PEM env var. Setting both is ambiguous, so the library rejects the configuration outright rather than guessing precedence.
Solutions
- Unset one of the two environment variables — keep either the file path or the inline PEM, not both.
- Standardize on the file variant (mount the CA as a file) in containerized deployments and remove the inline var from manifests.
- Audit the deployment environment (compose file, k8s env, shell profile) for both variable names.
Example fix
// before POSTGRES_CA_FILE=/certs/ca.crt POSTGRES_CA="-----BEGIN CERTIFICATE-----..." // after POSTGRES_CA_FILE=/certs/ca.crt # POSTGRES_CA removed
Defensive patterns
Strategy: validation
Validate before calling
func caEnvConflict() bool {
file := os.Getenv("POSTGRES_CA_FILE")
direct := os.Getenv("POSTGRES_CA")
return strings.TrimSpace(file) != "" && strings.TrimSpace(direct) != ""
} Try / catch
if err := checkCAEnvSanity(); err != nil {
log.Fatalf("CA config: %v", err)
} Prevention
- Pick one convention (file path recommended) and enforce it in deployment manifests.
- Lint docker-compose/k8s env blocks for both CA variable names in CI.
- Document the mutual exclusion where credentials are configured.
When it happens
Trigger: Calling ParsePoolConfig/NewPool while both the CA-file environment variable and the direct-PEM CA environment variable are set to non-empty values.
Common situations: A leftover CA path in the environment combined with an inline PEM injected by a secret manager; docker-compose or Helm chart exporting both variables; CI config accreting both settings over time.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- postgres: or is required in production
- postgres
- load system certificate pool
- postgres: CA certificate configured while TLS is disabled
- postgres: production connection includes a plaintext…
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/4c9cfe2a70cd01a6.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/postgresconfig/postgresconfig.go:83
for _, fallback := range config.ConnConfig.Fallbacks {
if fallback.TLSConfig == nil {
if production {
return nil, errors.New("postgres: production connection includes a plaintext fallback")
}
continue
}
fallback.TLSConfig.RootCAs = roots
fallback.TLSConfig.InsecureSkipVerify = false
fallback.TLSConfig.ServerName = fallback.Host
}
return config, nil
}
func caPEMFromEnvironment() (string, error) {
filePath := strings.TrimSpace(os.Getenv(caFileEnvironment))
direct := strings.TrimSpace(os.Getenv(caEnvironment))
if filePath != "" && direct != "" {
return "", fmt.Errorf("postgres: set only %s or %s, not both", caFileEnvironment, caEnvironment)
}
if filePath == "" {
return direct, nil
}
info, err := os.Stat(filePath)
if err != nil {
return "", fmt.Errorf("postgres: %s: %w", caFileEnvironment, err)
}
if !info.Mode().IsRegular() {
return "", fmt.Errorf("postgres: %s must point to a regular file", caFileEnvironment)
}
contents, err := os.ReadFile(filePath)
if err != nil {
return "", fmt.Errorf("postgres: read %s: %w", caFileEnvironment, err)
}
return strings.TrimSpace(string(contents)), nil
}
View on GitHub (pinned to 3ee70a1026)