{"record":{"id":"11bc25c5e3a6c6c8","repo":"JuliusBrussee/caveman","slug":"kms-plaintext-exceeds-d-bytes","errorCode":null,"errorMessage":"kms: plaintext exceeds %d bytes","messagePattern":"kms: plaintext exceeds (.+?) bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/kms/kms.go","lineNumber":180,"sourceCode":"\treturn client.Encrypt(ctx, plaintext)\n}\n\n// EncryptPayload wraps an artifact data key with the dedicated payload KEK.\nfunc EncryptPayload(ctx context.Context, plaintext []byte) ([]byte, error) {\n\tclient, err := FromPayloadEnvironment()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn client.Encrypt(ctx, plaintext)\n}\n\n// Encrypt delegates encryption to key manager.\nfunc (c *Client) Encrypt(ctx context.Context, plaintext []byte) ([]byte, error) {\n\tif len(plaintext) == 0 {\n\t\treturn nil, errors.New(\"kms: plaintext is empty\")\n\t}\n\tif len(plaintext) > maxPlaintextBytes {\n\t\treturn nil, fmt.Errorf(\"kms: plaintext exceeds %d bytes\", maxPlaintextBytes)\n\t}\n\tvar response struct {\n\t\tKeyID      string `json:\"key_id\"`\n\t\tCiphertext string `json:\"ciphertext\"`\n\t}\n\tif err := c.call(ctx, c.region, c.keyID, \"encrypt\", map[string]string{\n\t\t\"plaintext\": base64.StdEncoding.EncodeToString(plaintext),\n\t}, &response); err != nil {\n\t\treturn nil, err\n\t}\n\tif response.KeyID != c.keyID || strings.TrimSpace(response.Ciphertext) == \"\" {\n\t\treturn nil, errors.New(\"kms: invalid encrypt response\")\n\t}\n\tenvelope, err := json.Marshal(Envelope{Provider: c.provider, Region: c.region, KeyID: response.KeyID, Ciphertext: response.Ciphertext})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"kms: encode envelope: %w\", err)\n\t}\n\treturn append([]byte(prefix), envelope...), nil","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/kms/kms.go#L162-L198","documentation":"Encrypt rejects plaintext larger than maxPlaintextBytes because the Scaleway Key Manager API has a hard payload size limit; oversized input would only fail later at the HTTP layer. The error reports the exact byte cap via %d.","triggerScenarios":"Calling client.Encrypt(ctx, plaintext) with len(plaintext) > maxPlaintextBytes, e.g. encrypting a whole file, a large token blob, or concatenated secrets in one call.","commonSituations":"Encrypting database rows or config files wholesale instead of a data-encryption key; skipping chunking when migrating from a KMS without size limits.","solutions":["Check len(plaintext) against the library's limit before calling and split or reject oversized input.","Encrypt a small data-encryption key (DEK) and use it for bulk data locally (envelope encryption).","Chunk large payloads into multiple Encrypt calls and concatenate the envelopes."],"exampleFix":"// before\nenc, err := client.Encrypt(ctx, bigFileBytes) // kms: plaintext exceeds N bytes\n// after\nconst maxPlaintext = 32 << 10 // consult kms.maxPlaintextBytes\nif len(bigFileBytes) > maxPlaintext {\n    return fmt.Errorf(\"payload %d bytes exceeds KMS limit %d\", len(bigFileBytes), maxPlaintext)\n}\nenc, err := client.Encrypt(ctx, bigFileBytes)","handlingStrategy":"validation","validationCode":"if len(plaintext) == 0 {\n    return errors.New(\"nothing to encrypt\")\n}\nif len(plaintext) > maxPlaintextBytes {\n    return fmt.Errorf(\"plaintext %d > limit %d; use envelope encryption\", len(plaintext), maxPlaintextBytes)\n}","typeGuard":null,"tryCatchPattern":"enc, err := client.Encrypt(ctx, plaintext)\nif err != nil {\n    if strings.Contains(err.Error(), \"exceeds\") {\n        return fmt.Errorf(\"payload too large for KMS: %w\", err)\n    }\n    return err\n}","preventionTips":["Encrypt only small DEKs; do bulk encryption locally.","Check len(plaintext) before every Encrypt call.","Chunk large blobs rather than raising limits.","Document the size cap wherever the client is constructed."],"tags":["go","kms","encryption","size-limit"],"backgroundTag":"payload-too-large","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"}