{"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":null,"severity":"error","filePath":"middleware/csrf/csrf.go","lineNumber":271,"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":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/csrf/csrf.go#L253-L289","documentation":"Thrown at middleware/csrf/csrf.go:271 by getRawFromStorage() when storageManager.getRaw returns a non-nil error during token validation lookup. The CSRF middleware is trying to confirm the submitted token exists in storage and the Storage backend GET failed. The wrapped %w is the inner 'csrf: failed to get value from storage' error (153), which itself wraps the raw driver error.","triggerScenarios":"A state-changing request (POST/PUT/DELETE/...) reaches the CSRF middleware with a token, and storageManager.getRaw -> Storage.GetWithContext errors out: backend down, timeout, ctx cancelled, or auth failure.","commonSituations":"Session/CSRF Redis down during a deploy; storage credentials rotated but app not restarted; client disconnect mid-request; network partition to the session store.","solutions":["Inspect the wrapped error chain down to the driver error and fix the underlying backend issue (connectivity, auth, timeout).","Point cfg.Storage at a healthy backend and confirm connectivity at boot with a probe GET.","Tune the storage read timeout to fit within the request deadline.","Provide a custom cfg.ErrorHandler that returns a clear 5xx with retry guidance rather than leaking the storage error to the client.","Consider cfg.Session integration if you already run a session store, so CSRF reuses its (presumably healthy) backend."],"exampleFix":"// before\ncsrfStorage := redis.New()\napp.Use(csrf.New(csrf.Config{ Storage: csrfStorage }))\n\n// after: boot-time probe + clear error handler\nif _, err := csrfStorage.Get(\"__probe__\"); err != nil {\n    log.Fatalf(\"csrf storage unhealthy at boot: %v\", err)\n}\napp.Use(csrf.New(csrf.Config{\n    Storage: csrfStorage,\n    ErrorHandler: func(c fiber.Ctx, err error) error {\n        if strings.Contains(err.Error(), \"failed to fetch token from storage\") {\n            return c.Status(fiber.StatusServiceUnavailable).\n                SendString(\"session store temporarily unavailable; please retry\")\n        }\n        return c.Status(fiber.StatusForbidden).SendString(err.Error())\n    },\n}))","handlingStrategy":"try-catch","validationCode":"// At boot, confirm the CSRF storage backend is reachable.\nctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)\ndefer cancel()\nif _, err := store.GetWithContext(ctx, \"__csrf_probe__\"); err != nil {\n    log.Fatalf(\"csrf storage unhealthy: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"// Provide a CSRF ErrorHandler that degrades clearly on storage failures.\ncfg.ErrorHandler = func(c fiber.Ctx, err error) error {\n    if strings.Contains(err.Error(), \"failed to fetch token from storage\") {\n        c.Set(fiber.HeaderRetryAfter, \"5\")\n        return c.Status(fiber.StatusServiceUnavailable).\n            SendString(\"token store unavailable; retry shortly\")\n    }\n    return c.Status(fiber.StatusForbidden).SendString(err.Error())\n}","preventionTips":["Health-check the CSRF/session store at startup.","Tune the storage read timeout below the request deadline.","Prefer cfg.Session to reuse a resilient session store when one exists.","Monitor token-fetch error rate; alert on sustained failures."],"tags":["csrf","storage","network","security","fiber"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}