gofiber/fiber · error · ErrTokenNotFound
csrf: token not found
Error message
csrf: token not found
What it means
Returned by the CSRF middleware (csrf.go:23) when an unsafe HTTP method (POST, PUT, PATCH, DELETE, etc.) is received and the configured Extractor cannot find a CSRF token, or finds an empty string, or the token is not present in server-side storage (expired or never created). The middleware uses double-submit-cookie plus server-side storage validation, so the token must exist in the request payload/header AND in storage. Triggered from csrf.go:168, 175, 195, and 332.
Source
Thrown at middleware/csrf/csrf.go:23
"fmt"
"net/url"
"slices"
"strings"
"sync"
"time"
"github.com/gofiber/utils/v2"
utilsstrings "github.com/gofiber/utils/v2/strings"
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/extractors"
"github.com/gofiber/fiber/v3/internal/redact"
"github.com/gofiber/fiber/v3/internal/schemehost"
"github.com/gofiber/fiber/v3/middleware/logger"
)
var (
ErrTokenNotFound = errors.New("csrf: token not found")
ErrTokenInvalid = errors.New("csrf: token invalid")
ErrFetchSiteInvalid = errors.New("csrf: sec-fetch-site header invalid")
ErrRefererNotFound = errors.New("csrf: referer header missing")
ErrRefererInvalid = errors.New("csrf: referer header invalid")
ErrRefererNoMatch = errors.New("csrf: referer does not match host or trusted origins")
ErrOriginInvalid = errors.New("csrf: origin header invalid")
ErrOriginNoMatch = errors.New("csrf: origin does not match host or trusted origins")
errOriginNotFound = errors.New("origin not supplied or is null") // internal error, will not be returned to the user
dummyValue = []byte{'+'} // dummyValue is a placeholder value stored in token storage. The actual token validation relies on the key, not this value.
)
var registerLogContextTagsOnce sync.Once
// Handler for CSRF middleware
type Handler struct {
sessionManager *sessionManager
storageManager *storageManagerView on GitHub (pinned to 9a4c7e57fe)
Solutions
- Ensure the frontend reads the CSRF token from the cookie/endpoint and sends it on every unsafe-method request via the configured header or form field.
- If running multiple instances, configure a shared Storage (Redis, etc.) instead of the default in-memory storage so tokens are valid cluster-wide.
- Increase IdleTimeout / Expiration if tokens expire too quickly for your users.
- If SingleUseToken is enabled, ensure the client fetches a fresh token after each mutating request.
Example fix
// before — fetch POST with no CSRF header
fetch('/api/update', {method:'POST', credentials:'same-origin', body:data})
// after — read token from cookie and send as header
function getCookie(n){return document.cookie.match(n+'=([^;]+)')?.[1]}
fetch('/api/update', {method:'POST', credentials:'same-origin',
headers:{'X-Csrf-Token': getCookie('csrf_')}, body:data}) Defensive patterns
Strategy: validation
Validate before calling
// Frontend: ensure token is attached before sending unsafe requests
function safeFetch(url, opts={}) {
if (['POST','PUT','PATCH','DELETE'].includes(opts.method)) {
opts.headers = opts.headers || {}
opts.headers['X-Csrf-Token'] = getCookie('csrf_')
}
return fetch(url, {credentials:'same-origin', ...opts})
} Try / catch
// Customize the CSRF error handler to guide clients
app.Use(csrf.New(csrf.Config{
ErrorHandler: func(c fiber.Ctx, err error) error {
if errors.Is(err, csrf.ErrTokenNotFound) {
return c.Status(403).JSON(fiber.Map{"error":"CSRF token missing or expired. Fetch a new token."})
}
return c.Status(403).SendString(err.Error())
},
})) Prevention
- Always fetch and attach the CSRF token on unsafe requests from the frontend.
- Use shared Storage (Redis) in multi-instance deployments.
- Increase IdleTimeout if users spend long periods on forms.
When it happens
Trigger: A state-changing request (POST/PUT/PATCH/DELETE) is sent without the CSRF token in the location the Extractor is configured to read (default: form field '_csrf' or header 'X-Csrf-Token'); or the token cookie expired; or the token was already consumed (SingleUseToken=true); or the client sent a token that was never issued by this server instance (e.g. after a restart with in-memory storage).
Common situations: Frontend SPA forgot to include the CSRF token header on a fetch POST; cookie was cleared; load-balanced deployment with in-memory storage where the token was issued by a different instance; token expired due to IdleTimeout; using SingleUseToken and the client retried a request.
Related errors
- csrf: sec-fetch-site header invalid
- csrf: referer header missing
- csrf: referer header invalid
- csrf: referer does not match host or trusted origins
- csrf: origin header invalid
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/7785a79e7c20f8de.json.
Report an issue: GitHub.