{"record":{"id":"bab742972b8dd379","repo":"gofiber/fiber","slug":"domain-pattern-cannot-be-empty","errorCode":null,"errorMessage":"Domain pattern cannot be empty","messagePattern":"Domain pattern cannot be empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"domain.go","lineNumber":63,"sourceCode":"// maxDomainParts defines the maximum number of domain labels allowed (e.g., sub.domain.example.com = 4 parts).\n// This prevents DoS attacks from patterns or hostnames with excessive label counts.\n// RFC 1035 suggests 127 labels max, but we use a more conservative limit to prevent memory exhaustion.\nconst maxDomainParts = 16\n\n// parseDomainPattern parses a domain pattern like \":subdomain.example.com\"\n// into a domainMatcher. Parameter parts start with \":\".\n// Constant labels are lowercased per RFC 4343 (domain names are case-insensitive),\n// but parameter names are preserved as-is so that DomainParam lookups work with\n// the exact names the caller used (e.g., \":User\" → param name \"User\").\nfunc parseDomainPattern(pattern string) domainMatcher {\n\tpattern = utils.TrimSpace(pattern)\n\t// Trim trailing dot of a fully-qualified domain name (RFC 3986),\n\t// consistent with Fiber's own host normalization in Subdomains().\n\tpattern = utils.TrimRight(pattern, '.')\n\n\t// Validate pattern is not empty after trimming\n\tif pattern == \"\" {\n\t\tpanic(\"Domain pattern cannot be empty\")\n\t}\n\n\t// Enforce RFC 1035 total length limit on patterns\n\tif len(pattern) > 253 {\n\t\tpanic(fmt.Sprintf(\"Domain pattern '%s' exceeds RFC 1035 maximum of 253 characters (%d chars)\",\n\t\t\tpattern, len(pattern)))\n\t}\n\n\tparts := strings.Split(pattern, \".\")\n\n\t// Prevent DoS from patterns with excessive label counts\n\tif len(parts) > maxDomainParts {\n\t\tpanic(fmt.Sprintf(\"Domain pattern '%s' has %d parts, which exceeds the maximum of %d\",\n\t\t\tpattern, len(parts), maxDomainParts))\n\t}\n\n\tm := domainMatcher{\n\t\tparts:    make([]string, len(parts)),","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/domain.go#L45-L81","documentation":"parseDomainPattern normalizes the domain pattern (TrimSpace, then strips a trailing FQDN dot per RFC 3986) and rejects empty input. Domain routing requires at least one label, so an empty pattern is a caller bug caught at route registration.","triggerScenarios":"Calling app.Use(\"\", hostMiddleware) with a Domain constraint, or app.Domain(\"\") or a domain pattern that becomes empty after trimming whitespace and trailing dots (e.g. \".\" or \"   \").","commonSituations":"Reading the domain from config/env that was unset; passing the result of strings.Trim that yielded empty; user input not validated before being used as a domain pattern.","solutions":["Pass a non-empty domain string after trimming, e.g. \"api.example.com\".","Validate the source config: if domain == \"\" { return error } before calling Domain APIs.","Strip only the trailing dot yourself and ensure at least one label remains."],"exampleFix":"// before\napp.Domain(strings.Trim(cfg.Host, \".\"))  // \"\" when Host is unset\n\n// after\nhost := strings.TrimSpace(cfg.Host)\nif host == \"\" { return errors.New(\"host required\") }\napp.Domain(host)","handlingStrategy":"validation","validationCode":"// Reject empty domain patterns before calling Domain APIs\nfunc normalizeDomain(p string) (string, error) {\n    p = strings.TrimSpace(p)\n    p = strings.TrimRight(p, \".\")\n    if p == \"\" { return \"\", errors.New(\"empty domain pattern\") }\n    return p, nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate domain config at load time, not at route registration.","Treat an unset host env var as a fatal config error.","Centralize domain normalization in one helper."],"tags":["routing","domain","validation","startup"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}