gofiber/fiber · error

csrf: failed to fetch token from storage

Error message

csrf: failed to fetch token from storage: %w

What it means

Returned by getRawFromStorage when the underlying storageManager.getRaw fails while validating a submitted CSRF token. The token could not be read from the configured Storage or session backend, so CSRF verification cannot complete.

Solutions

  1. Inspect the wrapped error to classify (connectivity vs auth vs cancellation).
  2. Verify Storage connectivity and credentials are valid at runtime (ping outside the middleware).
  3. If using a custom Storage impl, ensure GetWithContext returns (nil, nil) for missing keys rather than an error.
  4. Tune connection pool and timeouts; consider failing closed (reject the request) per security posture rather than open.

Example fix

// before: any storage error fails verification opaquely
raw, err := storageManager.getRaw(c, token)
if err != nil {
    return nil, fmt.Errorf("csrf: failed to fetch token from storage: %w", err)
}

// after: classify and decide fail-open vs fail-closed explicitly
raw, err := storageManager.getRaw(c, token)
if err != nil {
    log.Error("csrf storage fetch failed:", err)
    // fail closed: reject on storage unavailability to preserve CSRF guarantee
    return nil, errCSRFTokenInvalid
}
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the configured Storage returns (nil,nil) for absent keys BEFORE
// going live — a custom impl that errors on miss triggers this.
func validateCsrfStorage(ctx context.Context, s fiber.Storage) error {
    got, err := s.GetWithContext(ctx, "__csrf_absent__")
    if err != nil {
        return fmt.Errorf("storage errors on absent key (must return nil,nil): %w", err)
    }
    if got != nil {
        return fmt.Errorf("storage returned non-nil for absent key")
    }
    return nil
}

Try / catch

// Decide fail-open vs fail-closed explicitly. For CSRF, fail closed.
raw, err := storageManager.getRaw(c, token)
if err != nil {
    log.Error("csrf storage fetch failed; rejecting request:", err)
    return c.Status(fiber.StatusServiceUnavailable).SendString("CSRF storage unavailable")
}

Prevention

When it happens

Trigger: A request carries a CSRF token and the middleware calls getRawFromStorage; storageManager.getRaw returns an error (external Storage GetWithContext failure). Occurs during token verification on POST/PUT/DELETE/etc. requests when cfg.Session is nil and cfg.Storage is configured.

Common situations: Redis/storage outage during CSRF validation; storage credentials/auth rotated; connection pool exhaustion under load; context cancellation on slow requests; misconfigured Storage interface implementation that errors on Get.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/425773d4ee4d91e2. Report an issue: GitHub.

Appendix: source

Thrown at middleware/csrf/csrf.go:274

// It accepts fiber.CustomCtx, fiber.Ctx, *fasthttp.RequestCtx, and context.Context.
// It returns nil if the handler does not exist.
func HandlerFromContext(ctx any) *Handler {
	if handler, ok := fiber.ValueFromContext[*Handler](ctx, handlerKey); ok {
		return handler
	}

	return nil
}

// getRawFromStorage returns the raw value from the storage for the given token
// returns nil if the token does not exist, is expired or is invalid
func getRawFromStorage(c fiber.Ctx, token string, cfg *Config, sessionManager *sessionManager, storageManager *storageManager) ([]byte, error) {
	if cfg.Session != nil {
		return sessionManager.getRaw(c, token, dummyValue), nil
	}
	raw, err := storageManager.getRaw(c, token)
	if err != nil {
		return nil, fmt.Errorf("csrf: failed to fetch token from storage: %w", err)
	}
	return raw, nil
}

// createOrExtendTokenInStorage creates or extends the token in the storage
func createOrExtendTokenInStorage(c fiber.Ctx, token string, cfg *Config, sessionManager *sessionManager, storageManager *storageManager) error {
	if cfg.Session != nil {
		sessionManager.setRaw(c, token, dummyValue, cfg.IdleTimeout)
		return nil
	}
	if err := storageManager.setRaw(c, token, dummyValue, cfg.IdleTimeout); err != nil {
		return fmt.Errorf("csrf: failed to store token in storage: %w", err)
	}
	return nil
}

func deleteTokenFromStorage(c fiber.Ctx, token string, cfg *Config, sessionManager *sessionManager, storageManager *storageManager) error {
	if cfg.Session != nil {

View on GitHub (pinned to a105acad6c)