gofiber/fiber · warning

failed to base64-decode value: %w

Error message

failed to base64-decode value: %w

What it means

Returned by DecryptCookie when base64.StdEncoding.DecodeString rejects the cookie value. DecryptCookie expects values produced by EncryptCookie, which emits standard base64; any value that is not valid standard-base64 triggers this. It is a wrapped encoding/base64 error.

Source

Thrown at middleware/encryptcookie/utils.go:70

	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
	}

	enc, err := base64.StdEncoding.DecodeString(value)
	if err != nil {
		return "", fmt.Errorf("failed to base64-decode value: %w", 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)
	}

	if len(enc) < gcm.NonceSize()+gcm.Overhead() {
		return "", ErrInvalidEncryptedValue
	}

	plaintext, err := gcm.Open(nil, nil, enc, []byte(name))
	if err != nil {

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Treat a base64-decode failure as 'no valid cookie' — re-issue a fresh encrypted cookie instead of surfacing the error to the user.
  2. Confirm every encrypted cookie was produced by EncryptCookie with the SAME base64.StdEncoding (not URLEncoding).
  3. Verify no reverse proxy is URL-decoding/rewriting the Cookie header value in transit.
  4. If mixing encodings, normalize the value to StdEncoding before calling DecryptCookie.

Example fix

// before
v, err := encryptcookie.DecryptCookie(name, c.Cookies(name), key)
if err != nil { return err }

// after — re-issue on any decode/decrypt failure
v, err := encryptcookie.DecryptCookie(name, c.Cookies(name), key)
if err != nil {
    // stale or foreign cookie: clear and continue unauthenticated
    c.Response().Header.Del("Set-Cookie")
    return c.Next()
}
Defensive patterns

Strategy: try-catch

Validate before calling

// cheap pre-check: standard base64, multiple of 4 chars, only valid alphabet
func isValidStdBase64(s string) bool {
    if len(s)%4 != 0 {
        return false
    }
    for i := 0; i < len(s); i++ {
        c := s[i]
        if !((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
            (c >= '0' && c <= '9') || c == '+' || c == '/' || c == '=') {
            return false
        }
    }
    return true
}

// usage
raw := c.Cookies(name)
if !isValidStdBase64(raw) {
    // re-issue instead of attempting DecryptCookie
    return c.Next()
}

Try / catch

v, err := encryptcookie.DecryptCookie(name, c.Cookies(name), key)
if err != nil {
    // log at debug, never expose — treat as absent cookie
    log.Debugf("cookie decrypt failed: %v", err)
    return c.Next()
}

Prevention

When it happens

Trigger: Calling DecryptCookie(name, value, key) where value is a plaintext cookie, URL-safe-base64 (-_ instead of +/), missing padding, truncated by a proxy, or hand-crafted by a client. The decode happens at utils.go:68-70 before any crypto runs.

Common situations: Migrating an app from plaintext cookies to encrypted cookies without invalidating old values; a CDN/proxy rewriting cookie characters; switching encoding std (URLEncoding vs StdEncoding); browser truncating very long cookies across domain boundaries.

Related errors


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