{"record":{"id":"dd45c364a33ffdf3","repo":"JuliusBrussee/caveman","slug":"kms-probe-encrypt-w","errorCode":null,"errorMessage":"kms: probe encrypt: %w","messagePattern":"kms: probe encrypt: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/kms/kms.go","lineNumber":324,"sourceCode":"\tif !runtimeenv.IsProduction() {\n\t\treturn nil\n\t}\n\tclient, err := FromPayloadEnvironment()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn client.Probe(ctx)\n}\n\n// Probe verifies live key access without persisting tenant data.\nfunc (c *Client) Probe(ctx context.Context) error {\n\tplaintext := make([]byte, 32)\n\tif _, err := rand.Read(plaintext); err != nil {\n\t\treturn fmt.Errorf(\"kms: generate probe: %w\", err)\n\t}\n\tenvelope, err := c.Encrypt(ctx, plaintext)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kms: probe encrypt: %w\", err)\n\t}\n\tdecrypted, err := c.Decrypt(ctx, envelope)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kms: probe decrypt: %w\", err)\n\t}\n\tif !bytes.Equal(decrypted, plaintext) {\n\t\treturn errors.New(\"kms: probe plaintext mismatch\")\n\t}\n\treturn nil\n}\n\nfunc validateLocation(region, keyID string) error {\n\tif !regionPattern.MatchString(region) {\n\t\treturn errors.New(\"kms: invalid Scaleway region\")\n\t}\n\tif !keyIDPattern.MatchString(keyID) {\n\t\treturn errors.New(\"kms: invalid Scaleway key ID\")\n\t}","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/shared/platform/kms/kms.go#L306-L342","documentation":"Probe generates 32 random bytes, Encrypts them, Decrypts the result, and compares; any failure in the Encrypt stage is wrapped as 'kms: probe encrypt: %w'. The underlying cause is whatever Encrypt or the HTTP call returned: plaintext checks pass (32 bytes), so realistic causes are auth failure, network errors, HTTP non-200, or an invalid encrypt response from the key manager.","triggerScenarios":"Running Probe at startup with an invalid/expired Scaleway auth token (surfaces as HTTP error from the call path); wrong region or key ID in config reaching the API; network egress blocked from the deployment; the key being disabled or deleted server-side.","commonSituations":"CI or local dev without KMS credentials; token rotated but the deployed secret not updated; firewall/proxy blocking api.scaleway.com; key deleted in console while config still references it.","solutions":["Read the wrapped error: 'returned HTTP 401/403' means token, 'HTTP 404' means region/keyID, 'request failed' means network","Verify the auth token and that it belongs to a project with access to the key","Confirm region and key ID match a live key in the Scaleway console","Allow egress to the key-manager API endpoint from the runtime environment"],"exampleFix":"// before\ncfg := kms.Config{Provider: kms.ProviderScaleway, Region: \"fr-par\", KeyID: \"deleted-key\", Token: staleToken}\n\n// after\ncfg := kms.Config{Provider: kms.ProviderScaleway, Region: \"fr-par\", KeyID: liveKeyID, Token: currentToken}","handlingStrategy":"try-catch","validationCode":"if err := client.Probe(ctx); err != nil { /* inspect wrapped cause before retrying */ }","typeGuard":null,"tryCatchPattern":"if err := client.Probe(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"probe encrypt\") {\n\t\tlog.Printf(\"KMS encrypt path unhealthy: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Run Probe in a health-check endpoint so failures surface before traffic","Wire alerts on probe failure to catch token/key/network drift early","Keep KMS config (token, region, keyID) in a managed secret that is validated on deploy"],"tags":["go","kms","probe","connectivity"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}