JuliusBrussee/caveman · critical
production KMS configuration
Error message
production KMS configuration: %w
What it means
RefuseProductionDefaults wraps a failure from kms.ValidateProduction() with the prefix 'production KMS configuration'. In production mode this library refuses to start unless the KMS is properly configured (real key IDs/credentials, not local/placeholder settings). It is thrown so the process fails fast instead of running production traffic against default or unusable KMS settings.
Solutions
- Configure the KMS variables kms.ValidateProduction() requires (key ID, region, credentials) with real production values.
- Inspect the wrapped cause (%w) in the error chain for the specific KMS problem and fix that first.
- If this is not a production deployment, run in local mode where KMS defaults are allowed.
- Verify cloud credentials are present in the deployment environment so the real KMS is resolvable.
Example fix
// before // prod deploy with no KMS key set CAVE_ENV=production ./cave // -> production KMS configuration: ... // after export CAVE_ENV=production export CAVE_KMS_KEY_ID=arn:aws:kms:us-east-1:123456789:key/abcd-... export AWS_REGION=us-east-1 ./cave
Defensive patterns
Strategy: validation
Validate before calling
if os.Getenv("CAVE_ENV") == "production" {
if os.Getenv("CAVE_KMS_KEY_ID") == "" {
return errors.New("CAVE_KMS_KEY_ID must be set before starting in production")
}
}
// then call env.RefuseProductionDefaults() Try / catch
if err := env.RefuseProductionDefaults(); err != nil {
var kmsErr error
if errors.As(err, &kmsErr) && strings.Contains(err.Error(), "production KMS configuration") {
log.Fatalf("fix KMS config: %v", err) // fail fast with the wrapped cause
}
return err
} Prevention
- Run RefuseProductionDefaults in CI against a production-like env to catch KMS gaps before deploy.
- Keep all secret/KMS material in a secret manager injected at deploy time, never defaulted.
- Log the full error chain (%w cause) to identify the exact KMS problem.
When it happens
Trigger: Calling RefuseProductionDefaults (e.g. at startup with production mode enabled) while kms.ValidateProduction() reports the KMS env/keys are unset, defaulted, or otherwise invalid.
Common situations: Deploying with CAVE_ENV=production but no KMS key configured; copying a local dev compose file to prod; upgrading to a version that added KMS validation; missing cloud credentials so the KMS resolver falls back to defaults.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- secretbox: production requires CAVE_KMS_PROVIDER=scaleway
- objectstore: S3_ENDPOINT is required in production
- postgres: production DATABASE_URL must be a Postgres URL
- production requires CAVE_PUBLIC_URL to be an HTTPS origin…
- secretbox: production refuses legacy local ciphertext
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/282f9ff639c6c330.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/env/env.go:74
// refusals and silently skip the rest. Whitespace and case are therefore folded
// in — the direction that turns MORE deployments on, never fewer.
func IsProduction() bool {
return runtimeenv.IsProduction()
}
func RefuseProductionDefaults() error {
if !IsProduction() {
return nil
}
if err := validateProductionTextSecrets([]string{
"CAVE_KEY_HASH_PEPPER",
"CAVE_JWT_SIGNING_KEY",
"CAVE_BOOTSTRAP_TOKEN",
}); err != nil {
return err
}
if err := kms.ValidateProduction(); err != nil {
return fmt.Errorf("production KMS configuration: %w", err)
}
return validateProductionPublicURL()
}
// RefuseGatewayProductionDefaults validates only material the public data plane
// consumes. Control-plane JWT/bootstrap secrets must never be injected into the
// gateway merely to satisfy a shared configuration check.
func RefuseGatewayProductionDefaults() error {
if !IsProduction() {
return nil
}
if err := validateProductionTextSecrets([]string{"CAVE_KEY_HASH_PEPPER"}); err != nil {
return err
}
if Bool("CAVE_REPLAY_ENABLED", false) {
if err := validateProductionTextSecrets([]string{"CAVE_ROUTER_REPLAY_TOKEN"}); err != nil {
return err
}View on GitHub (pinned to 3ee70a1026)