JuliusBrussee/caveman · error
kms: decrypt response plaintext is not valid base64
Error message
kms: decrypt response plaintext is not valid base64
What it means
Decrypt validates the KMS response and base64-decodes response.Plaintext. When the server (or a tampering intermediary) returns a Plaintext string that is not valid standard base64, decoding fails and this error replaces the raw decode error to keep the failure non-leaky.
Solutions
- Verify the response comes from the real Scaleway endpoint (no proxies re-encoding the body)
- If using a mock, ensure it encodes plaintext with base64.StdEncoding
- Log the raw response (in a safe environment) to confirm the malformed field; report unexpected server payloads to Scaleway if genuine
Example fix
// mock fix // before resp.Plaintext = string(plaintext) // after resp.Plaintext = base64.StdEncoding.EncodeToString(plaintext)
Defensive patterns
Strategy: try-catch
Validate before calling
// validate response before use (if you control the mock/producer)
if _, err := base64.StdEncoding.DecodeString(resp.Plaintext); err != nil {
return fmt.Errorf("producer emitted invalid base64: %w", err)
} Type guard
func isValidStdBase64(s string) bool {
_, err := base64.StdEncoding.DecodeString(s)
return err == nil
} Try / catch
plaintext, err := client.Decrypt(ctx, envelope)
if err != nil {
if err.Error() == "kms: decrypt response plaintext is not valid base64" {
// inspect/refresh envelope, alert on possible tampering
}
return fmt.Errorf("decrypt: %w", err)
} Prevention
- Encode mock payloads with base64.StdEncoding, not RawURLEncoding
- Avoid proxies/middleware that rewrite response bodies
- Pin the KMS API endpoint and version
When it happens
Trigger: KMS endpoint or an interceptor returning malformed/corrupted plaintext field, envelope KeyID matching but plaintext field mangled (e.g. URL-safe base64 or raw bytes instead of StdEncoding), proxy rewriting the response.
Common situations: Custom fake/mock KMS servers in tests emitting wrong base64 variant, middleware that re-encodes responses, or hitting the wrong API version/endpoint returning an unexpected payload shape.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- kms: decrypt response plaintext exceeds size limit
- envelope: decode wrapped key
- [extract-atlas] missing base64 const
- is not canonical base64
- must be base64 or null
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/4a626a6cceea17b2.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/kms/kms.go:262
}
if strings.TrimSpace(envelope.Ciphertext) == "" {
return nil, errors.New("kms: envelope ciphertext is empty")
}
var response struct {
KeyID string `json:"key_id"`
Plaintext string `json:"plaintext"`
}
if err := c.call(ctx, envelope.Region, envelope.KeyID, "decrypt", map[string]string{
"ciphertext": envelope.Ciphertext,
}, &response); err != nil {
return nil, err
}
if response.KeyID != envelope.KeyID || response.Plaintext == "" {
return nil, errors.New("kms: invalid decrypt response")
}
plaintext, err := base64.StdEncoding.DecodeString(response.Plaintext)
if err != nil {
return nil, errors.New("kms: decrypt response plaintext is not valid base64")
}
if len(plaintext) == 0 || len(plaintext) > maxPlaintextBytes {
return nil, errors.New("kms: decrypt response plaintext exceeds size limit")
}
return plaintext, nil
}
// ValidateProduction verifies real KMS configuration without network request.
func ValidateProduction() error {
if !runtimeenv.IsProduction() {
return nil
}
_, err := FromEnvironment()
return err
}
// ValidatePayloadProduction verifies the dedicated artifact-payload KEK is
// configured. This is separate from ValidateProduction because control-planeView on GitHub (pinned to 3ee70a1026)