{"record":{"id":"1fe530d43b22a78f","repo":"JuliusBrussee/caveman","slug":"ciphertext-too-short","errorCode":null,"errorMessage":"ciphertext too short","messagePattern":"ciphertext too short","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/secretbox/secretbox.go","lineNumber":132,"sourceCode":"\tif runtimeenv.IsProduction() &&\n\t\t!strings.EqualFold(strings.TrimSpace(os.Getenv(\"CAVE_KMS_ALLOW_LEGACY_LOCAL_DECRYPT\")), \"true\") {\n\t\treturn nil, fmt.Errorf(\"secretbox: production refuses legacy local ciphertext\")\n\t}\n\tkeyBytes, err := loadKey()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tblock, err := aes.NewCipher(keyBytes)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"aes cipher: %w\", err)\n\t}\n\tgcm, err := cipher.NewGCM(block)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"aes-gcm: %w\", err)\n\t}\n\tns := gcm.NonceSize()\n\tif len(envelope) < ns {\n\t\treturn nil, fmt.Errorf(\"ciphertext too short\")\n\t}\n\tnonce, ct := envelope[:ns], envelope[ns:]\n\tplain, err := gcm.Open(nil, nonce, ct, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"aes-gcm open: %w\", err)\n\t}\n\treturn plain, nil\n}\n\n// DecryptPayloadKey unwraps an artifact data-encryption key. KMS envelopes are\n// restricted to the configured payload key plus the explicit legacy secrets\n// key used before key separation.\nfunc DecryptPayloadKey(envelope []byte) ([]byte, error) {\n\tif kms.IsEnvelope(envelope) {\n\t\tctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\n\t\tdefer cancel()\n\t\tplaintext, err := kms.DecryptPayload(ctx, envelope)\n\t\tif err != nil {","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/766dce6b1394ebb56a3090748d5a0240a5aefb36/shared/platform/secretbox/secretbox.go#L114-L150","documentation":"Decrypt's local path found the envelope shorter than the GCM nonce size (12 bytes) — there is no nonce to split off, so the ciphertext is truncated, corrupt, or simply not a secretbox envelope. This length guard runs before gcm.Open, which would otherwise panic or misparse.","triggerScenarios":"Thrown at shared/platform/secretbox/secretbox.go:132 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check how the envelope was transported/stored — truncation usually happens in a VARCHAR column, log field, or copy-paste","Validate envelope length before storing and use bytea/base64 transport end to end","If the value is actually plaintext or another format, route it through the correct decode path","Discard unrecoverable fragments; there is no way to decrypt a truncated GCM ciphertext"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"766dce6b1394ebb56a3090748d5a0240a5aefb36","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}