gofiber/fiber · error

Domain pattern '%s' has %d parameters, which exceeds the max

Error message

Domain pattern '%s' has %d parameters, which exceeds the maximum of %d

What it means

Panics from domain.go:128 when a domain pattern declares more than maxParams (30) parameters. This cap (shared with path parameters, ctx.go:32) bounds the fixed-size parameter array in the request context; exceeding it would overflow that storage.

Source

Thrown at domain.go:128

			// Enforce RFC 1035 per-label length limit (63 characters)
			if len(part) > 63 {
				panic(fmt.Sprintf("Domain pattern '%s' has label '%s' exceeding RFC 1035 limit of 63 characters (%d chars)",
					pattern, part, len(part)))
			}
			// Validate label contains only valid ASCII domain characters (a-z, 0-9, hyphen).
			normalized := utilsstrings.ToLower(part)
			for _, ch := range normalized {
				if !isASCIIAlphanumeric(ch) && ch != '-' {
					panic(fmt.Sprintf("Domain pattern '%s' contains invalid character '%c' in label '%s'", pattern, ch, part))
				}
			}
			m.parts[i] = normalized
		}
	}

	// Check if the domain pattern has too many parameters
	if len(m.paramNames) > maxParams {
		panic(fmt.Sprintf("Domain pattern '%s' has %d parameters, which exceeds the maximum of %d",
			pattern, len(m.paramNames), maxParams))
	}

	return m
}

// match checks if a hostname matches the domain pattern.
// It returns true if matched and a slice of parameter values (parallel to paramNames).
// Uses a stack-allocated buffer to avoid heap allocation for typical domain names.
// Validates hostname to prevent DoS attacks from malicious input.
func (m *domainMatcher) match(hostname string) (bool, []string) { //nolint:gocritic // unnamedResult: named returns conflict with nonamedreturns linter
	// Trim trailing dot of a fully-qualified domain name (RFC 3986),
	// consistent with Fiber's own host normalization in Subdomains().
	hostname = utils.TrimRight(hostname, '.')

	// Validate hostname is not empty and not excessively long (DoS protection)
	// RFC 1035 limits domain names to 253 characters
	if hostname == "" || len(hostname) > 253 {

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Reduce the number of domain parameters to 30 or fewer.
  2. Capture only the variable labels you actually need; keep the rest constant.
  3. Move per-label variability into path routing or a lookup keyed on a single domain param.

Example fix

// before
pat := strings.Join(labels, ".") // > 30 ':' params
app.Domain(pat).Get("/", h)

// after - keep essential params, fix the rest
constLabels := []string{"svc", "example", "com"}
pat := ":tenant." + strings.Join(constLabels, ".")
app.Domain(pat).Get("/", h)
Defensive patterns

Strategy: validation

Validate before calling

n := 0
for _, label := range strings.Split(pattern, ".") {
    if strings.HasPrefix(label, ":") {
        n++
    }
}
if n > 30 {
    return fmt.Errorf("domain pattern has %d parameters, max 30", n)
}
app.Domain(pattern).Get("/", h)

Prevention

When it happens

Trigger: app.Domain(":a.:b.:c....example.com") with more than 30 ':'-prefixed labels in a single domain pattern.

Common situations: Machine-generated patterns that parameterize every label; misusing domain parameters to encode many tenants; a loop that appends ":x" labels.

Related errors


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