{"record":{"id":"425773d4ee4d91e2","repo":"gofiber/fiber","slug":"csrf-failed-to-fetch-token-from-storage-w","errorCode":null,"errorMessage":"csrf: failed to fetch token from storage: %w","messagePattern":"csrf: failed to fetch token from storage: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"middleware/csrf/csrf.go","lineNumber":274,"sourceCode":"// It accepts fiber.CustomCtx, fiber.Ctx, *fasthttp.RequestCtx, and context.Context.\n// It returns nil if the handler does not exist.\nfunc HandlerFromContext(ctx any) *Handler {\n\tif handler, ok := fiber.ValueFromContext[*Handler](ctx, handlerKey); ok {\n\t\treturn handler\n\t}\n\n\treturn nil\n}\n\n// getRawFromStorage returns the raw value from the storage for the given token\n// returns nil if the token does not exist, is expired or is invalid\nfunc getRawFromStorage(c fiber.Ctx, token string, cfg *Config, sessionManager *sessionManager, storageManager *storageManager) ([]byte, error) {\n\tif cfg.Session != nil {\n\t\treturn sessionManager.getRaw(c, token, dummyValue), nil\n\t}\n\traw, err := storageManager.getRaw(c, token)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"csrf: failed to fetch token from storage: %w\", err)\n\t}\n\treturn raw, nil\n}\n\n// createOrExtendTokenInStorage creates or extends the token in the storage\nfunc createOrExtendTokenInStorage(c fiber.Ctx, token string, cfg *Config, sessionManager *sessionManager, storageManager *storageManager) error {\n\tif cfg.Session != nil {\n\t\tsessionManager.setRaw(c, token, dummyValue, cfg.IdleTimeout)\n\t\treturn nil\n\t}\n\tif err := storageManager.setRaw(c, token, dummyValue, cfg.IdleTimeout); err != nil {\n\t\treturn fmt.Errorf(\"csrf: failed to store token in storage: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc deleteTokenFromStorage(c fiber.Ctx, token string, cfg *Config, sessionManager *sessionManager, storageManager *storageManager) error {\n\tif cfg.Session != nil {","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/csrf/csrf.go#L256-L292","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the wrapped error to classify (connectivity vs auth vs cancellation).","Verify Storage connectivity and credentials are valid at runtime (ping outside the middleware).","If using a custom Storage impl, ensure GetWithContext returns (nil, nil) for missing keys rather than an error.","Tune connection pool and timeouts; consider failing closed (reject the request) per security posture rather than open."],"exampleFix":"// before: any storage error fails verification opaquely\nraw, err := storageManager.getRaw(c, token)\nif err != nil {\n    return nil, fmt.Errorf(\"csrf: failed to fetch token from storage: %w\", err)\n}\n\n// after: classify and decide fail-open vs fail-closed explicitly\nraw, err := storageManager.getRaw(c, token)\nif err != nil {\n    log.Error(\"csrf storage fetch failed:\", err)\n    // fail closed: reject on storage unavailability to preserve CSRF guarantee\n    return nil, errCSRFTokenInvalid\n}","handlingStrategy":"validation","validationCode":"// Confirm the configured Storage returns (nil,nil) for absent keys BEFORE\n// going live — a custom impl that errors on miss triggers this.\nfunc validateCsrfStorage(ctx context.Context, s fiber.Storage) error {\n    got, err := s.GetWithContext(ctx, \"__csrf_absent__\")\n    if err != nil {\n        return fmt.Errorf(\"storage errors on absent key (must return nil,nil): %w\", err)\n    }\n    if got != nil {\n        return fmt.Errorf(\"storage returned non-nil for absent key\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Decide fail-open vs fail-closed explicitly. For CSRF, fail closed.\nraw, err := storageManager.getRaw(c, token)\nif err != nil {\n    log.Error(\"csrf storage fetch failed; rejecting request:\", err)\n    return c.Status(fiber.StatusServiceUnavailable).SendString(\"CSRF storage unavailable\")\n}","preventionTips":["Custom Storage impls must return (nil, nil) for missing keys, not an error.","Verify Storage connectivity and credentials at startup.","Keep CSRF Storage highly available — it gates every state-changing request."],"tags":["csrf","storage","auth","security","go","fiber"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}