{"id":"dfe2e8c0248d74cc","repo":"gofiber/fiber","slug":"csrf-failed-to-delete-key-q-w","errorCode":null,"errorMessage":"csrf: failed to delete key %q: %w","messagePattern":"csrf: failed to delete key %q: %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"middleware/csrf/storage_manager.go","lineNumber":73,"sourceCode":"\n// set data to storage or memory\nfunc (m *storageManager) setRaw(ctx context.Context, key string, raw []byte, exp time.Duration) error {\n\tif m.storage != nil {\n\t\tif err := m.storage.SetWithContext(ctx, key, raw, exp); err != nil {\n\t\t\treturn fmt.Errorf(\"csrf: failed to store key %q: %w\", m.logKey(key), err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tm.memory.Set(key, raw, exp)\n\treturn nil\n}\n\n// delete data from storage or memory\nfunc (m *storageManager) delRaw(ctx context.Context, key string) error {\n\tif m.storage != nil {\n\t\tif err := m.storage.DeleteWithContext(ctx, key); err != nil {\n\t\t\treturn fmt.Errorf(\"csrf: failed to delete key %q: %w\", m.logKey(key), err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tm.memory.Delete(key)\n\treturn nil\n}\n\nfunc (m *storageManager) logKey(key string) string {\n\tif m.shouldRedactKeys {\n\t\treturn redactedKey\n\t}\n\treturn key\n}\n","sourceCodeStart":55,"sourceCodeEnd":88,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/csrf/storage_manager.go#L55-L88","documentation":"Thrown at middleware/csrf/storage_manager.go:73 by storageManager.delRaw when m.storage.DeleteWithContext fails. This is the inner layer wrapped by error 152 (csrf: failed to delete token from storage); the wrapped %w is the raw driver delete error.","triggerScenarios":"Single-use token consumption or explicit Handler.DeleteToken triggers Storage.DeleteWithContext, and the backend rejects it: read-only failover replica, ACL missing DELETE, OOM, ctx cancelled, network error.","commonSituations":"Storage failover to a read-only replica; ACLs granting GET/SET but not DELETE; backend OOM; client disconnect; transient network error.","solutions":["Grant DELETE permission to the storage user in addition to GET/SET.","Avoid pointing CSRF at a read-only replica; use the writable primary.","Log delete failures and rely on IdleTimeout TTL to reclaim the token rather than failing the request.","Tune the storage write timeout to fit the request lifetime.","Resolve any backend capacity/connectivity issue surfaced by the wrapped error."],"exampleFix":"// before\napp.Use(csrf.New(csrf.Config{\n    Storage:        replicaOnly(), // read-only\n    SingleUseToken: true,\n}))\n\n// after: point at the writable primary; tolerate delete hiccups\napp.Use(csrf.New(csrf.Config{\n    Storage:        writablePrimary(),\n    SingleUseToken: true,\n    ErrorHandler: func(c fiber.Ctx, err error) error {\n        if strings.Contains(err.Error(), \"failed to delete key\") {\n            log.Printf(\"csrf delete failed (TTL reclaims): %v\", err)\n            return c.Next()\n        }\n        return c.Status(fiber.StatusForbidden).SendString(err.Error())\n    },\n}))","handlingStrategy":"fallback","validationCode":"// Confirm DELETE works at boot.\nctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)\ndefer cancel()\n_ = store.SetWithContext(ctx, \"__csrf_del_probe__\", []byte(\"+\"), time.Minute)\nif err := store.DeleteWithContext(ctx, \"__csrf_del_probe__\"); err != nil {\n    log.Fatalf(\"csrf storage DELETE denied: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"// Best-effort delete; IdleTimeout TTL reclaims the token anyway.\nif err := m.storage.DeleteWithContext(ctx, key); err != nil {\n    log.Printf(\"csrf delete failed for %q (TTL reclaims): %v\", m.logKey(key), err)\n    return nil\n}","preventionTips":["Grant DELETE permission to the storage user.","Point CSRF at the writable primary, never a read-only replica.","Rely on IdleTimeout TTL as the safety net for failed deletes.","Log delete failures distinctly to catch failover/ACL drift early."],"tags":["csrf","storage","network","security","fiber"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}