gofiber/fiber · warning · ErrOriginNoMatch

csrf: origin does not match host or trusted origins

Error message

csrf: origin does not match host or trusted origins

What it means

Returned by csrf.originMatchesHost (csrf.go:394) when the Origin header parses successfully on an unsafe-method request but its scheme+host does not match the request's own scheme+host and is not in the TrustedOrigins allowlist. This is the primary cross-origin CSRF rejection and fires before token validation, so a mismatched origin never reaches the token check.

Source

Thrown at middleware/csrf/csrf.go:29

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

// The contextKey type is unexported to prevent collisions with context keys defined in
// other packages.
type contextKey int

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Add every legitimate frontend origin to Config.TrustedOrigins.
  2. Use the subdomain wildcard 'https://*.example.com' to cover all subdomains of a domain.
  3. Ensure scheme consistency (serve the frontend over HTTPS if the API is HTTPS).
  4. Set Config.Next to skip CSRF on trusted internal/server-to-server routes that use a shared-secret auth instead.

Example fix

// before
app.Use(csrf.New())
// after
app.Use(csrf.New(csrf.Config{
  TrustedOrigins: []string{"https://app.example.com", "https://*.staging.example.com"},
}))
Defensive patterns

Strategy: validation

Validate before calling

// Validate that all expected client origins are trusted before deploy
frontendOrigins := []string{"https://app.example.com", "https://www.example.com"}
for _, o := range frontendOrigins {
    _, valid := url.Parse(o)
    if valid != nil || !slices.Contains(csrfCfg.TrustedOrigins, o) {
        log.Printf("WARN: frontend origin %s not trusted by CSRF", o)
    }
}

Prevention

When it happens

Trigger: An unsafe-method request (POST/PUT/PATCH/DELETE) arrives with Origin 'https://evil.com' or 'https://other.example.com' when the server host is 'api.example.com' and that origin is not in TrustedOrigins. The schemehost.Match at line 380 fails, and neither the exact trusted list (line 386) nor the subdomain wildcards (line 390) match.

Common situations: Frontend on a different domain/subdomain not whitelisted; scheme mismatch (http frontend vs https API); legitimate third-party integrations not added to TrustedOrigins; actual CSRF attack. Very common when separating frontend and API onto different subdomains during development.

Related errors


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/7b9fcb19e5330ada.json. Report an issue: GitHub.