{"record":{"id":"0593ef526954622c","repo":"golang/go","slug":"cipher-the-nonce-can-t-have-zero-length","errorCode":null,"errorMessage":"cipher: the nonce can't have zero length","messagePattern":"cipher: the nonce can't have zero length","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/cipher/gcm.go","lineNumber":208,"sourceCode":"\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ret, nil\n}\n\n// gcmAble is an interface implemented by ciphers that have a specific optimized\n// implementation of GCM. crypto/aes doesn't use this anymore, and we'd like to\n// eventually remove it.\ntype gcmAble interface {\n\tNewGCM(nonceSize, tagSize int) (AEAD, error)\n}\n\nfunc newGCMFallback(cipher Block, nonceSize, tagSize int) (AEAD, error) {\n\tif tagSize < gcmMinimumTagSize || tagSize > gcmBlockSize {\n\t\treturn nil, errors.New(\"cipher: incorrect tag size given to GCM\")\n\t}\n\tif nonceSize <= 0 {\n\t\treturn nil, errors.New(\"cipher: the nonce can't have zero length\")\n\t}\n\tif cipher, ok := cipher.(gcmAble); ok {\n\t\treturn cipher.NewGCM(nonceSize, tagSize)\n\t}\n\tif cipher.BlockSize() != gcmBlockSize {\n\t\treturn nil, errors.New(\"cipher: NewGCM requires 128-bit block cipher\")\n\t}\n\treturn &gcmFallback{cipher: cipher, nonceSize: nonceSize, tagSize: tagSize}, nil\n}\n\n// gcmFallback is only used for non-AES ciphers, which regrettably we\n// theoretically support. It's a copy of the generic implementation from\n// crypto/internal/fips140/aes/gcm/gcm_generic.go, refer to that file for more details.\ntype gcmFallback struct {\n\tcipher    Block\n\tnonceSize int\n\ttagSize   int\n}","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/cipher/gcm.go#L190-L226","documentation":"newGCMFallback requires nonceSize > 0 because a zero-length nonce breaks GCM's counter initialization (the J0 computation assumes at least one block worth of nonce processing). The check fires after the tag-size check and before the gcmAble fast-path.","triggerScenarios":"Calling cipher.NewGCMWithNonceSize(block, 0) — typically because the size argument was an uninitialized int (zero value), or because the caller derived nonceSize from a misconfigured constant.","commonSituations":"Reading nonceSize from a config struct whose field was never populated; passing `0` as a sentinel that the API does not honor; refactoring that left a temporary placeholder in place.","solutions":["Pass a positive nonce length; 12 (gcmStandardNonceSize) is strongly recommended.","Default to cipher.NewGCM(block) which uses the standard 12-byte nonce and avoids the question entirely.","Validate config-driven nonce sizes at load time: reject zero and negative values before they reach the constructor."],"exampleFix":"// before\na, err := cipher.NewGCMWithNonceSize(block, cfg.NonceSize) // cfg.NonceSize == 0\n// \"the nonce can't have zero length\"\n\n// after: explicit, standard nonce size\na, err := cipher.NewGCM(block) // 12-byte nonce\n// or\nif cfg.NonceSize <= 0 { cfg.NonceSize = 12 }\na, err := cipher.NewGCMWithNonceSize(block, cfg.NonceSize)","handlingStrategy":"validation","validationCode":"func newAEADSizedNonce(block cipher.Block, size int) (cipher.AEAD, error) {\n    if size <= 0 {\n        return nil, errors.New(\"nonce size must be positive\")\n    }\n    return cipher.NewGCMWithNonceSize(block, size)\n}","typeGuard":null,"tryCatchPattern":"a, err := cipher.NewGCMWithNonceSize(block, size)\nif err != nil && strings.Contains(err.Error(), \"nonce can't have zero length\") {\n    // Default to standard 12-byte nonce.\n    a, err = cipher.NewGCM(block)\n}","preventionTips":["Prefer cipher.NewGCM which uses the standard 12-byte nonce implicitly.","Reject zero or negative nonce sizes at config load time.","Treat an uninitialized NonceSize field as a configuration bug."],"tags":["crypto","gcm","argument-validation","nonce","configuration"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}