gofiber/fiber · critical

hostauthorization: host %q exceeds RFC 1035 maximum of %d ch

Error message

hostauthorization: host %q exceeds RFC 1035 maximum of %d characters (%d chars)

What it means

RFC 1035 caps a domain name at 253 characters total. validateHostLength (hostauthorization.go:67-71) panics when the normalized host exceeds maxDomainLength (253) so an over-long entry — which would be rejected by resolvers anyway — is caught at startup rather than silently never matching.

Source

Thrown at middleware/hostauthorization/hostauthorization.go:69

			continue
		}

		validateHostLength(h)

		if isWildcard {
			// Stored with leading dot so the hot-path HasSuffix check stays alloc-free.
			parsed.wildcardSuffixes = append(parsed.wildcardSuffixes, "."+h)
		} else {
			parsed.exact[h] = struct{}{}
		}
	}

	return parsed
}

func validateHostLength(host string) {
	if len(host) > maxDomainLength {
		panic(fmt.Sprintf("hostauthorization: host %q exceeds RFC 1035 maximum of %d characters (%d chars)",
			host, maxDomainLength, len(host)))
	}
	// IPv6 hosts contain colons and aren't dotted labels.
	if strings.IndexByte(host, ':') >= 0 {
		return
	}
	for label := range strings.SplitSeq(host, ".") {
		if len(label) > maxLabelLength {
			panic(fmt.Sprintf("hostauthorization: host %q has label %q exceeding RFC 1035 limit of %d characters (%d chars)",
				host, label, maxLabelLength, len(label)))
		}
	}
}

// normalizeHost strips port, trailing dot, and IPv6 brackets, lowercases,
// and converts IDN labels to Punycode (matching what browsers send).
func normalizeHost(host string) string {
	// Fast path for plain hostnames — avoids net.SplitHostPort's error allocation.

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Shorten the hostname; split deep hierarchies into shorter labels or use a wildcard parent.
  2. If the long name is generated, cap its length at the generator and reject over-length tenants at provisioning time.
  3. Confirm you did not accidentally concatenate multiple hostnames into one entry.

Example fix

// before
AllowedHosts: []string{"a.really.deeply.nested.tenant.subdomain.that.keeps.going.example.com"} // >253 chars

// after
AllowedHosts: []string{"*.example.com"} // match the deep subdomains via wildcard
Defensive patterns

Strategy: validation

Validate before calling

const maxDomain = 253

func validateHostTotalLength(hosts []string) error {
    for _, h := range hosts {
        if strings.HasPrefix(h, "*.") { h = h[2:] }
        if strings.Contains(h, ":") { continue } // IPv6
        if len(h) > maxDomain {
            return fmt.Errorf("host %q is %d chars, exceeds RFC 1035 max %d", h, len(h), maxDomain)
        }
    }
    return nil
}

if err := validateHostTotalLength(cfg.AllowedHosts); err != nil { log.Fatal(err) }

Prevention

When it happens

Trigger: An AllowedHosts entry whose normalized form (port stripped, trailing dot removed, lowercased, Punycode-encoded) exceeds 253 characters. IPv6 hosts (containing ':') skip the label check but still pass the total-length check.

Common situations: Dynamic/generated hostnames (e.g. long tenant-qualified names in a multi-tenant SaaS) that accumulate segments, or IDN domains whose Punycode encoding ('xn--...') is far longer than the readable form.

Related errors


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