golang/go · error
cipher: the nonce can't have zero length
Error message
cipher: the nonce can't have zero length
What it means
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.
Source
Thrown at src/crypto/cipher/gcm.go:208
if err != nil {
return nil, err
}
return ret, nil
}
// gcmAble is an interface implemented by ciphers that have a specific optimized
// implementation of GCM. crypto/aes doesn't use this anymore, and we'd like to
// eventually remove it.
type gcmAble interface {
NewGCM(nonceSize, tagSize int) (AEAD, error)
}
func newGCMFallback(cipher Block, nonceSize, tagSize int) (AEAD, error) {
if tagSize < gcmMinimumTagSize || tagSize > gcmBlockSize {
return nil, errors.New("cipher: incorrect tag size given to GCM")
}
if nonceSize <= 0 {
return nil, errors.New("cipher: the nonce can't have zero length")
}
if cipher, ok := cipher.(gcmAble); ok {
return cipher.NewGCM(nonceSize, tagSize)
}
if cipher.BlockSize() != gcmBlockSize {
return nil, errors.New("cipher: NewGCM requires 128-bit block cipher")
}
return &gcmFallback{cipher: cipher, nonceSize: nonceSize, tagSize: tagSize}, nil
}
// gcmFallback is only used for non-AES ciphers, which regrettably we
// theoretically support. It's a copy of the generic implementation from
// crypto/internal/fips140/aes/gcm/gcm_generic.go, refer to that file for more details.
type gcmFallback struct {
cipher Block
nonceSize int
tagSize int
}View on GitHub (pinned to b6b368adc5)
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.
Example fix
// before
a, err := cipher.NewGCMWithNonceSize(block, cfg.NonceSize) // cfg.NonceSize == 0
// "the nonce can't have zero length"
// after: explicit, standard nonce size
a, err := cipher.NewGCM(block) // 12-byte nonce
// or
if cfg.NonceSize <= 0 { cfg.NonceSize = 12 }
a, err := cipher.NewGCMWithNonceSize(block, cfg.NonceSize) Defensive patterns
Strategy: validation
Validate before calling
func newAEADSizedNonce(block cipher.Block, size int) (cipher.AEAD, error) {
if size <= 0 {
return nil, errors.New("nonce size must be positive")
}
return cipher.NewGCMWithNonceSize(block, size)
} Try / catch
a, err := cipher.NewGCMWithNonceSize(block, size)
if err != nil && strings.Contains(err.Error(), "nonce can't have zero length") {
// Default to standard 12-byte nonce.
a, err = cipher.NewGCM(block)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- crypto/cipher: use of GCM with arbitrary IVs is not allowed
- cipher: incorrect tag size given to GCM
- crypto/cipher: use of GCM with non-AES ciphers is not allowe
- cipher: NewGCMWithRandomNonce requires aes.Block
- cipher: NewGCM requires 128-bit block cipher
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/0593ef526954622c.
Report an issue: GitHub.