JuliusBrussee/caveman · critical
production KMS configuration: %w
Error message
production KMS configuration: %w
What it means
Thrown by RefuseProductionDefaults in shared/platform/env/env.go:74 when the process is in production mode and kms.ValidateProduction() rejects the KMS configuration. It is a wrapper: the 'production KMS configuration:' prefix adds context to the underlying KMS error, which names the actual defect. This is one of the boot-time refusal gates - in production the process exits rather than run on default KMS settings.
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 27d5a3981a)
Solutions
- Read the wrapped error text after the colon - it states the precise KMS defect; fix that (key id, credentials, or endpoint) first.
- Provide the production KMS configuration (key reference and auth) as specified by the kms package's ValidateProduction.
- Audit the deployed env for leftover dev/local KMS values and remove emulator settings.
- Re-run the binary/deploy; the gate passes once kms.ValidateProduction returns nil.
Example fix
# before CAVE_ENV=prod KMS_PROVIDER= # unset -> default # after CAVE_ENV=prod KMS_PROVIDER=cloud KMS_KEY_ID=projects/p/locations/eu/keyRings/cave/cryptoKeys/pepper
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-deploy: run the same gates CI runs
if err := env.RefuseProductionDefaults(); err != nil {
return fmt.Errorf("deploy blocked: %w", err)
} Try / catch
if err := env.RefuseProductionDefaults(); err != nil {
log.Fatalf("production config refused: %v", err) // read the wrapped KMS error after the colon
} Prevention
- Execute RefuseProductionDefaults against prod env in CI before any rollout.
- Keep a dedicated prod env manifest with KMS values, reviewed like code.
- Treat any 'production KMS configuration:' failure as a deploy blocker, never a warning.
When it happens
Trigger: IsProduction() is true (CAVE_ENV folded to prod) and the KMS setup fails its own production validation - typically default/placeholder KMS values, a missing key reference, or a dev-local KMS emulator setting left in place. The text-secret checks for CAVE_KEY_HASH_PEPPER, CAVE_JWT_SIGNING_KEY, and CAVE_BOOTSTRAP_TOKEN run first; only after they pass does the KMS check fire.
Common situations: Deploying to prod with the local/dev KMS defaults still in the env; adding KMS-backed encryption to a stack whose deployment templates never gained the KMS variables; renaming KMS env vars in the library without updating the manifest.
Related errors
- production requires an https:// CLICKHOUSE_URL (TLS only); C
- production refuses default or empty %s
- production requires %s to contain at least 32 characters
- production requires CAVE_PUBLIC_URL to be an HTTPS origin wi
- production refuses low-diversity %s
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/282f9ff639c6c330.
Report an issue: GitHub.