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

  1. If you wrote a custom Encryptor/Decryptor, replicate the decodeKey length validation (16/24/32) BEFORE calling aes.NewCipher.
  2. Audit any code path that constructs an AES cipher to confirm key length is enforced upstream.
  3. Run encryptcookie.ValidateKey(key) at startup; if it passes, error 158 cannot fire later via the public API.
  4. 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

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


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/6bb342649d1f142b.json. Report an issue: GitHub.