{"record":{"id":"2cd3532147d03fdc","repo":"JuliusBrussee/caveman","slug":"kms-probe-plaintext-mismatch","errorCode":null,"errorMessage":"kms: probe plaintext mismatch","messagePattern":"kms: probe plaintext mismatch","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/kms/kms.go","lineNumber":331,"sourceCode":"\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}\n\treturn nil\n}\n\nfunc (c *Client) call(ctx context.Context, region, keyID, operation string, input, output any) error {\n\tbody, err := json.Marshal(input)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kms: encode %s request: %w\", operation, err)","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/kms/kms.go#L313-L349","documentation":"Probe performs an encrypt-then-decrypt round trip against the configured key; if the bytes returned by Decrypt do not equal the original plaintext it reports a mismatch. This indicates the KMS path is not behaving transparently and should never happen with a healthy Scaleway endpoint.","triggerScenarios":"Running Probe against a mocked or faulty KMS endpoint whose decrypt output differs from encrypt input, corrupted responses, or an interceptor/test double that mangles payloads.","commonSituations":"Testing with a hand-rolled fake KMS, network middleboxes altering bodies, or a misconfigured base URL pointing at an incompatible KMS-compatible API.","solutions":["Point the client at the genuine Scaleway KMS endpoint and a valid key","Fix the mock/test double so Decrypt returns exactly the bytes passed to Encrypt","Inspect any proxy/TLS-terminating middleware that could corrupt the payload"],"exampleFix":"// mock fix\n// before\nreturn ciphertext[:len(ciphertext)-1], nil // truncated\n// after\nreturn plaintext, nil // store and return original plaintext","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := client.Probe(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"probe plaintext mismatch\") {\n\t\tlog.Error(\"KMS round trip corrupted — check endpoint/mocks/proxies\")\n\t}\n\treturn err\n}","preventionTips":["Run Probe at startup/health checks to catch corrupt KMS paths early","Use the real Scaleway endpoint in production; keep mocks faithful","Audit TLS-terminating proxies for body rewriting"],"tags":["kms","probe","integrity"],"backgroundTag":"unexpected-api-response-shape","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"}