{"record":{"id":"2a69c5283a3a9c67","repo":"golang/go","slug":"cipher-message-authentication-failed","errorCode":null,"errorMessage":"cipher: message authentication failed","messagePattern":"cipher: message authentication failed","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/crypto/cipher/gcm.go","lineNumber":269,"sourceCode":"\tif alias.AnyOverlap(out, additionalData) {\n\t\tpanic(\"crypto/cipher: invalid buffer overlap of output and additional data\")\n\t}\n\n\tvar H, counter, tagMask [gcmBlockSize]byte\n\tg.cipher.Encrypt(H[:], H[:])\n\tderiveCounter(&H, &counter, nonce)\n\tgcmCounterCryptGeneric(g.cipher, tagMask[:], tagMask[:], &counter)\n\n\tgcmCounterCryptGeneric(g.cipher, out, plaintext, &counter)\n\n\tvar tag [gcmTagSize]byte\n\tgcmAuth(tag[:], &H, &tagMask, out[:len(plaintext)], additionalData)\n\tcopy(out[len(plaintext):], tag[:])\n\n\treturn ret\n}\n\nvar errOpen = errors.New(\"cipher: message authentication failed\")\n\nfunc (g *gcmFallback) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\tif len(nonce) != g.nonceSize {\n\t\tpanic(\"crypto/cipher: incorrect nonce length given to GCM\")\n\t}\n\tif g.tagSize < gcmMinimumTagSize {\n\t\tpanic(\"crypto/cipher: incorrect GCM tag size\")\n\t}\n\n\tif len(ciphertext) < g.tagSize {\n\t\treturn nil, errOpen\n\t}\n\tif uint64(len(ciphertext)) > uint64((1<<32)-2)*gcmBlockSize+uint64(g.tagSize) {\n\t\treturn nil, errOpen\n\t}\n\n\tret, out := sliceForAppend(dst, len(ciphertext)-g.tagSize)\n\tif alias.InexactOverlap(out, ciphertext) {","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/cipher/gcm.go#L251-L287","documentation":"errOpen is the sentinel returned by gcmFallback.Open (GCM decryption) when authentication fails. In the shown region it fires when the ciphertext is shorter than the configured tag size; the same error is returned later when the recomputed GCM authentication tag does not match the tag embedded in the ciphertext, which signals tampering or a key/nonce/additional-data mismatch.","triggerScenarios":"Calling gcm.Open(...) with len(ciphertext) < g.tagSize; or with ciphertext whose trailing tag bytes do not match the tag recomputed from the plaintext, nonce, key, or additionalData.","commonSituations":"Truncated ciphertext in transit; bit-flips or corruption on the wire; nonce reuse across messages under the same key; decrypting with the wrong key; passing different additionalData than was used at encryption time.","solutions":["Verify the full ciphertext including the trailing tag is passed unmodified to Open.","Ensure encrypt and decrypt sides use the exact same key, nonce, and additionalData.","Never reuse a nonce with the same key; generate a fresh random 12-byte nonce per message.","Treat this error as a security event (possible forgery); do not silently retry or strip the tag."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"plaintext, err := gcm.Open(nil, nonce, ciphertext, aad)\nif err != nil {\n    if errors.Is(err, cipher.ErrAuth) /* or the package's auth sentinel */ {\n        // Authentication failure: treat as tampering/forgery. Do NOT retry\n        // with truncated tags or fall back; log and reject the message.\n        return ErrCiphertextRejected\n    }\n    return err\n}","preventionTips":["Generate a fresh random 12-byte nonce per message and transmit it alongside the ciphertext.","Pin the same additionalData on both encrypt and decrypt sides; treat it as part of the contract.","Never reuse a (key, nonce) pair; rotate keys if a nonce collision is possible.","Log authentication failures as security events, not routine errors."],"tags":["crypto","gcm","authentication","aead","go","security"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}