golang/go · error
cipher: NewGCM requires 128-bit block cipher
Error message
cipher: NewGCM requires 128-bit block cipher
What it means
GCM (Galois/Counter Mode) is mathematically defined only for block ciphers with a 128-bit (16-byte) block. This fallback code path runs when the cipher does not implement the gcmAble interface (i.e. no hardware/assembly acceleration) and its BlockSize() is not gcmBlockSize (16). AES in all key sizes has 128-bit blocks, so it passes; ciphers like Blowfish (64-bit) do not.
Source
Thrown at src/crypto/cipher/gcm.go:214
// 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
}
func (g *gcmFallback) NonceSize() int {
return g.nonceSize
}
func (g *gcmFallback) Overhead() int {View on GitHub (pinned to b6b368adc5)
Solutions
- Use an AES block cipher: block, err := aes.NewCipher(key) then cipher.NewGCM(block).
- If you must use a 64-bit block cipher, choose a different AEAD construction (e.g. CTR mode + HMAC) instead of GCM.
- Guard before calling NewGCM: verify block.BlockSize() == 16 and surface a clear error otherwise.
Example fix
// before block, _ := blowfish.NewCipher(key) gcm, _ := cipher.NewGCM(block) // after block, _ := aes.NewCipher(key) // AES has a 128-bit block gcm, _ := cipher.NewGCM(block)
Defensive patterns
Strategy: validation
Validate before calling
// Guard before NewGCM for any non-AES or custom cipher:
func newGCM(block cipher.Block) (cipher.AEAD, error) {
if block.BlockSize() != 16 {
return nil, fmt.Errorf("GCM needs a 128-bit block cipher, got %d-byte blocks", block.BlockSize())
}
return cipher.NewGCM(block)
} Type guard
func isAESBlockSize(b cipher.Block) bool { return b.BlockSize() == 16 } Prevention
- Always pair GCM with AES (aes.NewCipher); document this invariant at the call site.
- For custom cipher.Block implementations, assert BlockSize()==16 in a unit test.
- Avoid passing legacy 64-bit block ciphers (Blowfish, DES) into NewGCM.
When it happens
Trigger: Calling cipher.NewGCM(block) (which routes to newGCMFallback when the cipher is not gcmAble) with a Block whose BlockSize() != 16. Concretely: wrapping a blowfish.NewCipher block, a Twofish-style 128-bit block that lacks gcmAble implementation details aside, or any custom cipher.Block returning a non-16 BlockSize.
Common situations: Selecting GCM as the AEAD over a legacy or non-AES block cipher; writing a custom Block implementation; migrating code that paired GCM with an unexpected cipher; assuming GCM works with any cipher.
Related errors
- cipher: incorrect tag size given to GCM
- cipher: the nonce can't have zero length
- cipher: NewGCM requires 128-bit block cipher
- cipher: message authentication failed
- crypto/cipher: incorrect nonce length given to SetNoncePrefi
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/4412ef5d8c2131ff.
Report an issue: GitHub.