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

  1. Use the full Scaleway KMS key UUID from the console/API (e.g. 85xyt4nm-1baf-51ad-a37b-6bf4b3725440)
  2. strings.TrimSpace the key ID read from env or config files
  3. 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

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


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)