hashicorp/terraform · error
Error decoding encryption key
Error message
Error decoding encryption key: %s
What it means
Thrown when the bytes read from encryption_key are not valid standard base64. The GCS backend expects a 32-byte key supplied base64-encoded (consistent with the GCS customer-supplied encryption docs), so after reading it decodes with base64.StdEncoding.
Solutions
- Regenerate the key as base64 of 32 random bytes: `openssl rand -base64 32`.
- Strip trailing whitespace/newlines from the key content before supplying it.
- Ensure you are using standard (not URL-safe) base64 with correct '=' padding.
- Confirm the decoded length is exactly 32 bytes.
Example fix
// before — raw bytes or wrong encoding export TF_ENC_KEY=$(openssl rand 32 | base64) # newline included // after export TF_ENC_KEY=$(openssl rand -base64 32 | tr -d '\n')
Defensive patterns
Strategy: validation
Validate before calling
decoded, err := base64.StdEncoding.DecodeString(strings.TrimSpace(kc))
if err != nil {
return fmt.Errorf("encryption_key must be base64(32 bytes); regenerate with `openssl rand -base64 32`")
}
if len(decoded) != 32 {
return fmt.Errorf("encryption_key decodes to %d bytes, expected 32", len(decoded))
} Type guard
func isValidGCSEncryptionKey(s string) bool {
b, err := base64.StdEncoding.DecodeString(strings.TrimSpace(s))
return err == nil && len(b) == 32
} Prevention
- Generate keys only with `openssl rand -base64 32` and trim newlines.
- Add a CI lint that validates the supplied key length after base64 decode.
When it happens
Trigger: readPathOrContents returns content, but base64.StdEncoding.DecodeString returns an error — e.g., the key is raw bytes, hex-encoded, URL-safe base64, contains whitespace/newlines that StdEncoding rejects, or has wrong padding.
Common situations: User generated a key with `openssl rand 32` and pasted raw bytes; used `base64.URLStringEncoding`; the file has a trailing newline that breaks strict StdEncoding; key was generated by a tool emitting hex.
Related errors
- Error loading encryption key
- Error loading credentials
- impersonate_service_account_delegates elements must not be…
- the string provided in credentials is neither valid json…
- address argument is required
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/c3e19f83ba90db82.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/gcs/backend.go:281
key := data.String("encryption_key")
if key != "" {
kc, err := readPathOrContents(key)
if err != nil {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("Error loading encryption key: %s", err),
)
}
// The GCS client expects a customer supplied encryption key to be
// passed in as a 32 byte long byte slice. The byte slice is base64
// encoded before being passed to the API. We take a base64 encoded key
// to remain consistent with the GCS docs.
// https://cloud.google.com/storage/docs/encryption#customer-supplied
// https://github.com/GoogleCloudPlatform/google-cloud-go/blob/def681/storage/storage.go#L1181
k, err := base64.StdEncoding.DecodeString(kc)
if err != nil {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("Error decoding encryption key: %s", err),
)
}
b.encryptionKey = k
}
// Customer-managed encryption
kmsName := data.String("kms_encryption_key")
if kmsName != "" {
b.kmsKeyName = kmsName
}
return nil
}
View on GitHub (pinned to d32a084675)