JuliusBrussee/caveman · error
kms: invalid Scaleway key ID
Error message
kms: invalid Scaleway key ID
What it means
validateLocation checks the key ID against keyIDPattern (a UUID-formatted identifier in Scaleway KMS). A key ID that is empty, malformed, or from another provider fails this check at New or when Decrypt composes the key URL.
Solutions
- Use the full Scaleway KMS key UUID from the console/API (e.g. 85xyt4nm-1baf-51ad-a37b-6bf4b3725440)
- strings.TrimSpace the key ID read from env or config files
- Validate the UUID format (uuid.Parse) before constructing the client
Example fix
// before
keyID := os.Getenv("KMS_KEY") // "my-master-key"
// after
keyID := strings.TrimSpace(os.Getenv("KMS_KEY_ID")) // full UUID
if _, err := uuid.Parse(keyID); err != nil { return err } Defensive patterns
Strategy: validation
Validate before calling
if _, err := uuid.Parse(strings.TrimSpace(cfg.KeyID)); err != nil {
return fmt.Errorf("KMS key ID must be a UUID: %q", cfg.KeyID)
} Prevention
- Store the full Scaleway key UUID, not names/aliases/ARNs
- Trim whitespace when reading IDs from env or files
- Validate key IDs with uuid.Parse at config load
When it happens
Trigger: Config.KeyID empty, containing dashes/spaces or a key name/alias instead of the UUID, or a truncated ID from a copy-paste.
Common situations: Using an AWS KMS key ARN or an alias in a Scaleway config, missing KEY_ID env var, or IDs extracted from logs with whitespace.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- kms: invalid Scaleway region
- kms: unsupported provider
- cave_breaker_retry_backoff_invalid
- cave_breaker_retry_requires_budget
- cave_breaker_retry_spend_invalid
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/4acec50b301c584c.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/kms/kms.go:341
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 {
body, err := json.Marshal(input)
if err != nil {
return fmt.Errorf("kms: encode %s request: %w", operation, err)
}
endpoint := c.apiBaseURL + "/key-manager/v1alpha1/regions/" + url.PathEscape(region) +
"/keys/" + url.PathEscape(keyID) + "/" + operation
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(body))
if err != nil {
return fmt.Errorf("kms: create %s request: %w", operation, err)
}
req.Header.Set("content-type", "application/json")
req.Header.Set("accept", "application/json")
req.Header.Set("x-auth-token", c.token)View on GitHub (pinned to 3ee70a1026)