gofiber/fiber · error

hostauthorization: host

Error message

hostauthorization: host %q has label %q exceeding RFC 1035 limit of %d characters (%d chars)

What it means

hostauthorization enforces RFC 1035 per-label length: each dot-separated label of a hostname must be at most 63 characters. validateHostLength splits the host on '.' and panics when any single label exceeds maxLabelLength (63). This catches a single over-long segment even when the total domain length is within the 253-char budget.

Solutions

  1. Shorten the offending label to 63 characters or fewer (DNS will reject anything longer anyway).
  2. If the long value is an identifier, move it into a path or query parameter rather than a DNS label.
  3. Validate each label at config-load time and reject entries with any label > 63 chars before constructing the middleware.

Example fix

// before — tenant ID is 72 chars, used as a label
hostauthorization.New(hostauthorization.Config{
    AllowedHosts: []string{"<72-char-tenant-id>.example.com"},
})

// after — keep tenants out of DNS labels
hostauthorization.New(hostauthorization.Config{
    AllowedHosts: []string{" tenants.example.com"},
}) // route by /t/<tenant-id> instead
Defensive patterns

Strategy: validation

Validate before calling

func validateHostLabels(host string) error {
    for _, label := range strings.Split(host, ".") {
        if len(label) > 63 {
            return fmt.Errorf("label %q exceeds 63 chars", label)
        }
    }
    return nil
}

Prevention

When it happens

Trigger: An AllowedHosts entry containing a label longer than 63 chars, e.g. a slug or token accidentally used as a subdomain label. IPv6 hosts (which contain ':') are skipped by this check; it only applies to dotted DNS names.

Common situations: Using a tenant UUID or long opaque token as a hostname label (e.g. aaaa...63chars....example.com); pasting a URL-encoded value as a label; generating hostnames programmatically without label-length awareness.

Related errors


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

Appendix: source

Thrown at middleware/hostauthorization/hostauthorization.go:78

			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.
	if host != "" && host[0] != '[' && strings.IndexByte(host, ':') < 0 {
		host = trimOneTrailingDot(host)
		host = utilsstrings.ToLower(host)
		return toPunycode(host)
	}

	if h, _, err := net.SplitHostPort(host); err == nil {
		host = h
	} else {

View on GitHub (pinned to a105acad6c)