gofiber/fiber · critical
failed to create AES cipher: %w
Error message
failed to create AES cipher: %w
What it means
Thrown at middleware/encryptcookie/utils.go:49 inside EncryptCookie() when aes.NewCipher(keyDecoded) returns an error. In the normal public flow this is effectively unreachable: decodeKey() already ran first and validated the decoded length is exactly 16, 24, or 32 bytes - the only condition aes.NewCipher rejects. The check exists as a defensive guard; seeing it means the key length validation was bypassed (e.g. calling decodeKey-equivalent logic partially) or a future Go crypto/aes change.
Source
Thrown at middleware/encryptcookie/utils.go:49
return keyDecoded, nil
}
// validateKey checks if the provided base64-encoded key is of valid length.
func validateKey(key string) error {
_, err := decodeKey(key)
return err
}
// EncryptCookie Encrypts a cookie value with specific encryption key
func EncryptCookie(name, value, key string) (string, error) {
keyDecoded, err := decodeKey(key)
if err != nil {
return "", err
}
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)
}
ciphertext := gcm.Seal(nil, nil, []byte(value), []byte(name))
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// DecryptCookie Decrypts a cookie value with specific encryption key
func DecryptCookie(name, value, key string) (string, error) {
keyDecoded, err := decodeKey(key)
if err != nil {
return "", err
}
View on GitHub (pinned to 9a4c7e57fe)
Solutions
- If you wrote a custom Encryptor/Decryptor, replicate the decodeKey length validation (16/24/32) BEFORE calling aes.NewCipher.
- Audit any code path that constructs an AES cipher to confirm key length is enforced upstream.
- Run encryptcookie.ValidateKey(key) at startup; if it passes, error 158 cannot fire later via the public API.
- On exotic platforms, confirm crypto/aes is functional with a smoke test (aes.NewCipher(make([]byte, 16))).
Example fix
// before: custom decryptor skips length validation
cfg.Decryptor = func(name, value, key string) (string, error) {
raw, _ := base64.StdEncoding.DecodeString(key) // skip length check
block, err := aes.NewCipher(raw) // can fail -> error 158
...
}
// after: reuse decodeKey for validation, then construct the cipher
raw, err := decodeKey(key) // validates base64 + 16/24/32 length
if err != nil { return "", err }
block, err := aes.NewCipher(raw) // safe; length already enforced
if err != nil {
return "", fmt.Errorf("failed to create AES cipher: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
// At startup, confirm the key produces a working AES cipher.
if err := encryptcookie.ValidateKey(key); err != nil {
log.Fatalf("invalid cookie key: %v", err)
}
// Optional: round-trip a sample to exercise the AES path.
if _, err := encryptcookie.EncryptCookie("probe", "x", key); err != nil {
log.Fatalf("AES cipher construction failed: %v", err)
} Type guard
// Ensure any custom encryptor enforces AES key lengths before constructing the cipher.
func isAESKeyLen(raw []byte) bool {
switch len(raw) {
case 16, 24, 32: return true
}
return false
} Try / catch
// In a custom encryptor, never skip the length check that decodeKey provides.
raw, err := decodeKey(key) // validates base64 + 16/24/32 length
if err != nil { return "", err }
block, err := aes.NewCipher(raw)
if err != nil {
return "", fmt.Errorf("failed to create AES cipher: %w", err)
} Prevention
- Reuse encryptcookie.decodeKey in custom encryptors rather than re-implementing key handling.
- Run a round-trip smoke test (encrypt then decrypt) at startup.
- Keep key-length validation upstream of any aes.NewCipher call.
- On exotic platforms, smoke-test crypto/aes availability before serving traffic.
When it happens
Trigger: Only fires if aes.NewCipher is handed a key whose length is not 16/24/32. Via EncryptCookie/DecryptCookie that cannot happen because decodeKey enforces those lengths first. Realistically seen only in custom forks that skip the validation, or in tests calling aes.NewCipher directly with a malformed key.
Common situations: Custom Decryptor/Encryptor override that re-implements the key handling without the length check; an internal refactor that reorders decodeKey and aes.NewCipher; AES-NI unavailable on an exotic platform returning an unexpected error (very unlikely).
Related errors
- failed to create GCM mode: %w
- encryption key must be 16, 24, or 32 bytes
- failed to base64-decode key: %w
- failed to base64-decode value: %w
- failed to decrypt ciphertext: %w
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/6bb342649d1f142b.json.
Report an issue: GitHub.