JuliusBrussee/caveman · error
kms: probe decrypt: %w
Error message
kms: probe decrypt: %w
What it means
The second stage of Probe: encryption succeeded, but Decrypt of the just-produced envelope failed, wrapped as 'kms: probe decrypt: %w'. Because the envelope was generated by the same client moments earlier, config mismatches (provider/region/keyID) are unlikely; realistic causes are an API-side decrypt failure, HTTP error on the decrypt call, or an invalid decrypt response payload.
Source
Thrown at shared/platform/kms/kms.go:328
if err != nil {
return err
}
return client.Probe(ctx)
}
// Probe verifies live key access without persisting tenant data.
func (c *Client) Probe(ctx context.Context) error {
plaintext := make([]byte, 32)
if _, err := rand.Read(plaintext); err != nil {
return fmt.Errorf("kms: generate probe: %w", err)
}
envelope, err := c.Encrypt(ctx, plaintext)
if err != nil {
return fmt.Errorf("kms: probe encrypt: %w", err)
}
decrypted, err := c.Decrypt(ctx, envelope)
if err != nil {
return fmt.Errorf("kms: probe decrypt: %w", err)
}
if !bytes.Equal(decrypted, plaintext) {
return errors.New("kms: probe plaintext mismatch")
}
return nil
}
func validateLocation(region, keyID string) error {
if !regionPattern.MatchString(region) {
return errors.New("kms: invalid Scaleway region")
}
if !keyIDPattern.MatchString(keyID) {
return errors.New("kms: invalid Scaleway key ID")
}
return nil
}
func (c *Client) call(ctx context.Context, region, keyID, operation string, input, output any) error {View on GitHub (pinned to 27d5a3981a)
Solutions
- Check the wrapped error for the specific stage (HTTP status vs response validation)
- Review the key's IAM policy: the calling token needs both encrypt and decrypt permissions
- Retry the probe once — a transient API error between the two calls is plausible
- If response validation fails consistently, verify the package version matches the current key-manager API
Example fix
// before
// service-account policy: { "effect": "allow", "action": "kms_encrypt" }
// after
// service-account policy:
// { "effect": "allow", "action": ["kms_encrypt", "kms_decrypt"] } Defensive patterns
Strategy: retry
Validate before calling
if err := client.Probe(ctx); err != nil { /* distinguish decrypt-stage failure: likely IAM or transient */ } Try / catch
err := client.Probe(ctx)
for attempt := 0; err != nil && strings.Contains(err.Error(), "probe decrypt") && attempt < 2; attempt++ {
time.Sleep(200 * time.Millisecond)
err = client.Probe(ctx)
} Prevention
- Grant the calling token both encrypt and decrypt permissions on the key
- Retry the probe once before declaring the KMS unhealthy
- Include probe-stage in error reporting to speed up IAM diagnosis
When it happens
Trigger: Scaleway key policy allowing encrypt but not decrypt on the token's service account; transient API failure between the two calls; decrypt response missing/blank plaintext causing 'invalid decrypt response'; envelope size or base64 issues never occur here since Encrypt just produced it.
Common situations: Least-privilege IAM policies granting encrypt-only; intermittent API errors during startup checks; API version change altering the decrypt response shape caught by strict response validation.
Related errors
- kms: probe encrypt: %w
- production KMS configuration: %w
- kms: unsupported provider %q
- kms: plaintext exceeds %d bytes
- kms: decode envelope: %w
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/beb64bf2c6c0dd71.
Report an issue: GitHub.