{"record":{"id":"d18ec27e183a8100","repo":"JuliusBrussee/caveman","slug":"aes-gcm-w","errorCode":null,"errorMessage":"aes-gcm: %w","messagePattern":"aes-gcm: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/secretbox/secretbox.go","lineNumber":76,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"secretbox: KMS encrypt: %w\", err)\n\t\t}\n\t\treturn wrapped, nil\n\t}\n\tif runtimeenv.IsProduction() {\n\t\treturn nil, fmt.Errorf(\"secretbox: production requires CAVE_KMS_PROVIDER=scaleway\")\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\tnonce := make([]byte, gcm.NonceSize())\n\tif _, err := rand.Read(nonce); err != nil {\n\t\treturn nil, fmt.Errorf(\"nonce entropy: %w\", err)\n\t}\n\t// Seal appends the ciphertext+tag to nonce, so the returned slice is the\n\t// full nonce||ciphertext envelope.\n\treturn gcm.Seal(nonce, nonce, plaintext, nil), nil\n}\n\n// EncryptPayloadKey wraps an artifact data-encryption key. Production uses the\n// dedicated payload KEK; local development retains the same AES-GCM envelope as\n// other local secrets.\nfunc EncryptPayloadKey(plaintext []byte) ([]byte, error) {\n\tif useKMS() {\n\t\tctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\n\t\tdefer cancel()\n\t\twrapped, err := kms.EncryptPayload(ctx, plaintext)","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/secretbox/secretbox.go#L58-L94","documentation":"cipher.NewGCM(block) wraps the AES block cipher in Galois/Counter Mode. In the Go standard library this call only fails if the underlying block's block size is not 16 bytes, which cannot happen with a successfully constructed aes.Block, so this error is effectively unreachable in practice. It is kept as a defensive wrap in case the block construction or crypto backend changes.","triggerScenarios":"Practically never with the standard crypto/aes block: it would require aes.NewCipher to succeed but return a block whose BlockSize() != 16, e.g. only conceivable with a custom or replaced crypto backend or unusual build (FIPS module mismatch).","commonSituations":"Almost only seen in exotic environments: patched/regulated crypto builds, vendored crypto replacements, or a bug report worth forwarding upstream. If you see it, the key was fine (it passed aes.NewCipher) and the failure is environmental.","solutions":["Verify the binary is built against the standard crypto/aes and crypto/cipher packages (check vendoring and replace directives in go.mod).","Rebuild without custom crypto replacements: go build with a clean module graph.","Check for any FIPS or custom cipher injection via build tags or init-time package replacement.","If it persists on the standard toolchain, file an upstream Go issue with go version output."],"exampleFix":"// before: go.mod replace directive swapping crypto internals\nreplace crypto/cipher => ./vendor/fips-cipher\n\n// after: use standard library\ndelete the replace directive, then: go mod tidy && go build","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"out, err := secretbox.Encrypt(pt)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"aes-gcm:\") {\n        // crypto backend invariant broken; escalate, not retryable\n        log.Fatalf(\"crypto backend invariant violated: %v\", err)\n    }\n    return err\n}","preventionTips":["Do not replace or vendor the standard crypto packages.","Pin and regularly update the Go toolchain; avoid unofficial forks for crypto-sensitive builds.","Include a startup AES-GCM self-test (encrypt/decrypt a fixed blob) in health checks.","Keep go.mod free of replace directives touching crypto/*."],"tags":["encryption","aes-gcm","go","crypto"],"backgroundTag":"internal-invariant-violation","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"}