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

  1. Read the wrapped error text after the colon - it states the precise KMS defect; fix that (key id, credentials, or endpoint) first.
  2. Provide the production KMS configuration (key reference and auth) as specified by the kms package's ValidateProduction.
  3. Audit the deployed env for leftover dev/local KMS values and remove emulator settings.
  4. 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

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


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/282f9ff639c6c330. Report an issue: GitHub.