gofiber/fiber · warning

csrf: token invalid

Error message

csrf: token invalid

What it means

Returned by middleware/csrf during Double Submit Cookie validation when the token extracted from the request (header/form/etc.) does not match the value of the CSRF cookie. The compare is constant-time; a mismatch means the submitted token was not bound to the browser's cookie, the canonical CSRF attack signal, so the request is rejected.

Source

Thrown at middleware/csrf/csrf.go:25

	"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/headerlookup"
	"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 *storageManager
	config         Config

View on GitHub (pinned to a105acad6c)

Solutions

  1. Re-fetch the token from a fresh GET before the mutation so token and cookie are in sync.
  2. Confirm the extractor reads from a channel other than the CSRF cookie (header/form), as the source comment warns.
  3. Avoid concurrent token-rotating requests in the same session, or handle this error by refreshing and retrying.
  4. Make sure the cookie is actually present and not being blocked so the comparison has two valid sides.

Example fix

// before: custom extractor reads the cookie (no protection)
Extractor: csrf.CookieExtractor(CookieName)
// after: read token from a header the client controls
Extractor: csrf.HeaderExtractor("X-CSRF-Token")
Defensive patterns

Strategy: try-catch

Try / catch

if errors.Is(err, csrf.ErrTokenInvalid) {
    // token/cookie mismatch: instruct client to refresh token, then retry
    return c.Status(fiber.StatusForbidden).SendString("refresh csrf token")
}

Prevention

When it happens

Trigger: The submitted token differs from the cookie value: client sent a stale token from an old cookie, two browser tabs holding different tokens, a token fabricated by an attacker who cannot read the cookie, or a custom Extractor that reads the same cookie (which the code warns provides no protection).

Common situations: User had multiple sessions/tabs and the cookie rotated; cookie was refreshed by a concurrent GET between read and submit; frontend cached an old token; a custom extractor pulls the token from the cookie itself, defeating the double-submit check.

Understand the failure class

Related errors


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