gofiber/fiber · warning

csrf: sec-fetch-site header invalid

Error message

csrf: sec-fetch-site header invalid

What it means

Returned by middleware/csrf.validateSecFetchSite when the Sec-Fetch-Site header is present but malformed. The header either has multiple values (headerlookup reports it as present-but-duplicated) or holds a token other than the four Fetch-standard values (same-origin, same-site, cross-site, none). No real browser sends anything else, so the request is treated as crafted.

Solutions

  1. If the client is a browser, do nothing: it always sends a valid token.
  2. If the client is a known non-browser, stop sending Sec-Fetch-Site or set one of the four valid tokens.
  3. Fix proxies that append/duplicate the header so only one valid value arrives.
  4. Use cfg.Next to exempt a specific trusted path if a non-browser legitimately needs it.

Example fix

// before: curl sets an invalid token
curl -H 'Sec-Fetch-Site: foo' -X POST ...
// after: omit it or use a valid token
curl -H 'Sec-Fetch-Site: same-origin' -X POST ...
Defensive patterns

Strategy: validation

Try / catch

if errors.Is(err, csrf.ErrFetchSiteInvalid) {
    // non-browser client sent a bad Sec-Fetch-Site; reject or fix the client
    return c.Status(fiber.StatusForbidden).SendString("invalid fetch metadata")
}

Prevention

When it happens

Trigger: A non-safe request with a Sec-Fetch-Site header set to an invalid token, or a Sec-Fetch-Site header duplicated in the request. Runs before origin/referer checks on every unsafe method.

Common situations: A non-browser client (curl, a proxy, a security scanner) setting Sec-Fetch-Site to a bogus value; a misconfigured reverse proxy appending a second Sec-Fetch-Site; a testing tool that sets the header to an empty-ish or custom string.

Related errors


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

Appendix: source

Thrown at middleware/csrf/csrf.go:26

	"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)