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

  1. Check the wrapped error for the specific stage (HTTP status vs response validation)
  2. Review the key's IAM policy: the calling token needs both encrypt and decrypt permissions
  3. Retry the probe once — a transient API error between the two calls is plausible
  4. 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

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


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