{"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/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/kms/kms.go#L306-L342","documentation":"Probe performs a live Encrypt of random bytes to verify key access; any Encrypt failure is re-wrapped as \"kms: probe encrypt: %w\". This surfaces the underlying cause (size guard, HTTP failure, invalid API response, or envelope encoding) while making clear it happened during the probe round trip, not on tenant data.","triggerScenarios":"Calling Probe when the underlying Encrypt fails: empty/oversized plaintext (not applicable to the fixed 32-byte probe), Scaleway API returning non-200, invalid or missing key_id/ciphertext in the response, or network/timeout errors inside client.call.","commonSituations":"Expired or missing x-auth-token; wrong region/keyID in config; key deleted or access revoked; egress blocked from the host to the Key Manager endpoint; API version drift.","solutions":["Unwrap the chained error (%w) to see the root cause from Encrypt/call.","Verify the API token is valid and not expired; check key existence and IAM permissions in the target region.","Confirm network egress to the Scaleway Key Manager endpoint and DNS resolution.","Run New with the correct region/keyID and re-Probe after fixing credentials or connectivity."],"exampleFix":"// before\nif err := client.Probe(ctx); err != nil { log.Fatal(err) } // kms: probe encrypt: kms: ...\n// after\nif err := client.Probe(ctx); err != nil {\n    var root = err\n    for errors.Unwrap(root) != nil { root = errors.Unwrap(root) }\n    log.Fatalf(\"probe failed (root cause: %v)\", root)\n}","handlingStrategy":"try-catch","validationCode":"if token == \"\" {\n    return errors.New(\"Scaleway API token missing; set x-auth-token credential\")\n}\nif _, err := url.Parse(apiBaseURL + \"/key-manager\"); err != nil {\n    return fmt.Errorf(\"bad KMS endpoint: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := client.Probe(ctx); err != nil {\n    var apiErr *kms.APIError // or inspect the unwrapped chain\n    if errors.As(err, &apiErr) {\n        return fmt.Errorf(\"key manager rejected probe (status %d): %w\", apiErr.Status, err)\n    }\n    return err\n}","preventionTips":["Call Probe at startup to fail fast on bad credentials or network.","Rotate tokens before expiry and store them in a secret manager.","Unwrap %w chains to find the root Encrypt failure.","Monitor egress/DNS to the Key Manager endpoint in restricted networks."],"tags":["go","kms","probe","encryption","api"],"backgroundTag":"upstream-api-error","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}