gofiber/fiber · error
failed to decrypt ciphertext
Error message
failed to decrypt ciphertext: %w
What it means
Returned by DecryptCookie when gcm.Open fails — the GCM authentication tag did not verify. This is the canonical 'wrong key, wrong cookie name, or tampered ciphertext' signal. The wrapped error is crypto/cipher's 'cipher: message authentication failed'.
Solutions
- Confirm the same key that encrypted the cookie is being used to decrypt.
- Confirm the cookie name passed to DecryptCookie matches the one passed to EncryptCookie (it is GCM additional data).
- Ensure both sides use cipher.NewGCMWithRandomNonce (this middleware's nonce layout prepends the random nonce).
- On key rotation, invalidate old cookies and force re-issue rather than attempting decrypt.
Example fix
// before: name mismatch breaks AAD
plaintext, _ := encryptcookie.DecryptCookie("session", value, key)
// after
plaintext, err := encryptcookie.DecryptCookie("sess", value, key)
if err != nil {
c.ClearCookie("sess")
return c.Redirect("/login")
} Defensive patterns
Strategy: try-catch
Try / catch
plain, err := encryptcookie.DecryptCookie(name, value, key)
if err != nil {
// GCM auth failed: wrong key, wrong name, or tampered value
c.ClearCookie(name)
return c.Redirect("/login")
} Prevention
- Keep the cookie name identical on encrypt and decrypt (it is GCM additional data).
- Rotate keys by invalidating old cookies, not by attempting cross-key decrypt.
- Use cipher.NewGCMWithRandomNonce consistently (this middleware's layout).
When it happens
Trigger: DecryptCookie(name, value, key) where the AES-GCM tag fails to verify: the key differs from the one used to encrypt, the cookie name (used as additional data) changed, the ciphertext/nonce bytes were modified, or the value was produced by a different GCM variant (NewGCM with explicit nonce vs NewGCMWithRandomNonce).
Common situations: Rotating the encryption key without invalidating sessions, renaming the cookie (the name is bound into the AAD), swapping EncryptCookie for a different GCM implementation, clients tampering with cookies, or copying a cookie value between environments with different keys.
Related errors
- failed to create GCM mode
- encryption key must be 16, 24, or 32 bytes
- failed to base64-decode key
- failed to create AES cipher
- decode SHA256 password: invalid length
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/fb6b8c50b2cd5e54.
Report an issue: GitHub.
Appendix: source
Thrown at middleware/encryptcookie/utils.go:89
}
block, err := aes.NewCipher(keyDecoded)
if err != nil {
return "", fmt.Errorf("failed to create AES cipher: %w", err)
}
gcm, err := cipher.NewGCMWithRandomNonce(block)
if err != nil {
return "", fmt.Errorf("failed to create GCM mode: %w", err)
}
if len(enc) < gcm.NonceSize()+gcm.Overhead() {
return "", ErrInvalidEncryptedValue
}
plaintext, err := gcm.Open(nil, nil, enc, []byte(name))
if err != nil {
return "", fmt.Errorf("failed to decrypt ciphertext: %w", err)
}
return string(plaintext), nil
}
// GenerateKey returns a random string of 16, 24, or 32 bytes.
// The length of the key determines the AES encryption algorithm used:
// 16 bytes for AES-128, 24 bytes for AES-192, and 32 bytes for AES-256-GCM.
func GenerateKey(length int) string {
if length != 16 && length != 24 && length != 32 {
panic(ErrInvalidKeyLength)
}
key := make([]byte, length)
if _, err := rand.Read(key); err != nil {
panic(err)
}View on GitHub (pinned to a105acad6c)