gofiber/fiber · error

[CSRF] Invalid origin format in configuration:

Error message

[CSRF] Invalid origin format in configuration:

What it means

The CSRF middleware pre-parses cfg.TrustedOrigins for origin validation. An entry containing '://*.' (wildcard subdomain) is de-wildcarded and passed to normalizeOrigin; if that returns invalid (unparseable URL, embedded '*' in host, userinfo, empty host, or a non-root path/query/fragment), CSRF startup panics with the masked original value.

Source

Thrown at middleware/csrf/csrf.go:91

	var sessionManager *sessionManager
	var storageManager *storageManager
	if cfg.Session != nil {
		sessionManager = newSessionManager(cfg.Session)
	} else {
		storageManager = newStorageManager(cfg.Storage, redactKeys)
	}

	// Pre-parse trusted origins
	trustedOrigins := []string{}
	trustedSubOrigins := []subdomain{}

	for _, origin := range cfg.TrustedOrigins {
		trimmedOrigin := utils.TrimSpace(origin)
		if i := strings.Index(trimmedOrigin, "://*."); i != -1 {
			withoutWildcard := trimmedOrigin[:i+len("://")] + trimmedOrigin[i+len("://*."):]
			isValid, normalizedOrigin := normalizeOrigin(withoutWildcard)
			if !isValid {
				panic("[CSRF] Invalid origin format in configuration:" + maskValue(origin))
			}
			schemeSep := strings.Index(normalizedOrigin, "://") + len("://")
			sd := subdomain{prefix: normalizedOrigin[:schemeSep], suffix: normalizedOrigin[schemeSep:]}
			trustedSubOrigins = append(trustedSubOrigins, sd)
		} else {
			isValid, normalizedOrigin := normalizeOrigin(trimmedOrigin)
			if !isValid {
				panic("[CSRF] Invalid origin format in configuration:" + maskValue(origin))
			}
			trustedOrigins = append(trustedOrigins, normalizedOrigin)
		}
	}

	// Create the handler outside of the returned function
	handler := &Handler{
		config:         cfg,
		sessionManager: sessionManager,
		storageManager: storageManager,

View on GitHub (pinned to a105acad6c)

Solutions

  1. Use the exact form 'https://*.example.com' with no path, query, fragment, or wildcard-port suffix.
  2. If a specific port is needed, attach it to a non-wildcard origin: 'https://api.example.com:8443'.
  3. Pre-validate TrustedOrigins entries with net/url.Parse before building the Config.

Example fix

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

Strategy: validation

Validate before calling

func validTrustedWildcard(o string) bool {
    t := strings.TrimSpace(o)
    i := strings.Index(t, "://*.")
    if i < 0 {
        return false
    }
    base := t[:i+len("://")] + t[i+len("://*."):]
    u, err := url.Parse(base)
    if err != nil || u.User != nil || u.Host == "" || strings.Contains(u.Host, "*") ||
        (u.Path != "" && u.Path != "/") || u.RawQuery != "" || u.Fragment != "" {
        return false
    }
    return true
}
for _, o := range cfg.TrustedOrigins {
    if strings.Contains(o, "://*.") && !validTrustedWildcard(o) {
        return fmt.Errorf("invalid trusted wildcard origin %q", o)
    }
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        log.Fatalf("CSRF trusted origin rejected: %v", r)
    }
}()
csrf.New(cfg)

Prevention

When it happens

Trigger: csrf.New(csrf.Config{ TrustedOrigins: []string{"https://*.example.com/api", "https://*.", "https://*:8443"} }) — any wildcard-subdomain origin whose de-wildcarded form fails normalizeOrigin (e.g. trailing path, missing host, port on the wildcard).

Common situations: Listing a trusted SPA origin with its path; using a wildcard with no base domain; pasting a full Origin header (with path/query) into TrustedOrigins; mixing port and wildcard forms.

Related errors


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