gofiber/fiber · error
Domain pattern ' ' contains empty parameter name at position
Error message
Domain pattern '%s' contains empty parameter name at position %d
What it means
Inside parseDomainPattern, labels starting with ':' are treated as domain parameters (e.g. :tenant.example.com). A bare ':' (length 1) means the parameter name is missing, which would make the captured value unusable, so it panics with the label position.
Solutions
- Always give parameter labels a name: ":tenant.example.com" not ":.example.com".
- Validate parameter labels before registering: a label starting with ':' must have len > 1.
- If the parameter is optional, omit the label entirely instead of emitting an empty parameter.
Example fix
// before
app.Domain(":.example.com")
// after
app.Domain(":tenant.example.com") Defensive patterns
Strategy: validation
Validate before calling
// Ensure every parameter label has a name
func validateParamLabels(p string) error {
for i, label := range strings.Split(p, ".") {
if label == ":" {
return fmt.Errorf("empty parameter name at position %d", i)
}
}
return nil
} Prevention
- Always name parameter labels (:tenant, not :).
- Validate templated patterns before registering them.
- Document the parameter-label syntax for route authors.
When it happens
Trigger: Passing a pattern like ":.example.com" or "example.:" where a parameter label has no name.
Common situations: Typing a colon without the name; templating that emits ':' when a variable is empty; refactor that introduced a bare parameter marker.
Related errors
- Domain pattern cannot be empty
- Domain pattern ' ' contains empty label at position
- Domain pattern ' ' contains invalid character '%c' in label
- Domain pattern ' ' contains invalid parameter name ' ' with…
- Domain pattern ' ' exceeds RFC 1035 maximum of 253…
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/eea7447685490db8.
Report an issue: GitHub.
Appendix: source
Thrown at domain.go:94
panic(fmt.Sprintf("Domain pattern '%s' has %d parts, which exceeds the maximum of %d",
pattern, len(parts), maxDomainParts))
}
m := domainMatcher{
parts: make([]string, len(parts)),
numParts: len(parts),
}
for i, part := range parts {
// Validate no empty labels (e.g., "example..com" is invalid)
if part == "" {
panic(fmt.Sprintf("Domain pattern '%s' contains empty label at position %d", pattern, i))
}
if part[0] == ':' {
// Validate parameter name is not empty
if len(part) == 1 {
panic(fmt.Sprintf("Domain pattern '%s' contains empty parameter name at position %d", pattern, i))
}
paramName := part[1:]
// Validate parameter name contains only ASCII-safe characters (a-z, A-Z, 0-9, underscore, hyphen).
// Using explicit ASCII ranges rather than unicode.IsLetter/IsDigit to reject non-ASCII
// characters that are invalid in DNS names.
for _, ch := range paramName {
if !isASCIIAlphanumeric(ch) && ch != '_' && ch != '-' {
panic(fmt.Sprintf("Domain pattern '%s' contains invalid parameter name '%s' with character '%c'", pattern, paramName, ch))
}
}
m.paramIdx = append(m.paramIdx, i)
m.paramNames = append(m.paramNames, paramName) // preserve original case
m.parts[i] = part // keep ":param" marker for matching
} else {
// Only lowercase constant labels (RFC 4343)
// 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)",View on GitHub (pinned to a105acad6c)