gofiber/fiber · warning · ErrForbiddenHost

hostauthorization: forbidden host

Error message

hostauthorization: forbidden host

What it means

Returned by hostauthorization middleware (config.go:10) when the request's Host header, after normalization (port stripped, trailing dot removed, IPv6 brackets removed, lowercased, Punycode-converted), either fails to parse or does not match any entry in AllowedHosts (exact or wildcard) nor the AllowedHostsFunc fallback. The default ErrorHandler responds with 403 Forbidden (config.go:61-63). This is a Host header validation middleware that prevents host-header injection / virtual-host confusion attacks.

Source

Thrown at middleware/hostauthorization/config.go:10

package hostauthorization

import (
	"errors"

	"github.com/gofiber/fiber/v3"
)

// ErrForbiddenHost is returned when the Host header does not match any allowed host.
var ErrForbiddenHost = errors.New("hostauthorization: forbidden host")

// Config defines the config for the host authorization middleware.
type Config struct {
	// Next defines a function to skip this middleware when returned true.
	// Use this to exclude health check endpoints or other paths from host validation.
	//
	// Optional. Default: nil
	Next func(c fiber.Ctx) bool

	// AllowedHostsFunc is a dynamic validator called only when no static
	// AllowedHosts rule matches. Receives the normalized hostname: port stripped,
	// trailing dot removed, IPv6 brackets removed, lowercased.
	// Return true to allow.
	//
	// Optional. Default: nil
	AllowedHostsFunc func(host string) bool

	// ErrorHandler is called when a request is rejected.

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Add all legitimate hostnames to AllowedHosts including 'localhost' and IPs for development/health-checks.
  2. Use AllowedHostsFunc for dynamic validation (e.g. database-backed host lists) when static rules are insufficient.
  3. Set Config.Next to skip host validation for health-check endpoints.
  4. For subdomains use the '*.example.com' wildcard form; list the apex separately since wildcards do not match the bare domain.

Example fix

// before
app.Use(hostauthorization.New(hostauthorization.Config{
  AllowedHosts: []string{"example.com"},
}))
// after — cover apex, www, staging, and localhost
app.Use(hostauthorization.New(hostauthorization.Config{
  AllowedHosts: []string{"example.com", "www.example.com", "*.staging.example.com", "localhost", "127.0.0.1"},
  Next: func(c fiber.Ctx) bool { return c.Path() == "/health" },
}))
Defensive patterns

Strategy: validation

Validate before calling

// Verify all expected hosts are allowed at startup
allowed := map[string]bool{}
for _, h := range cfg.AllowedHosts { allowed[h] = true }
for _, expected := range []string{"example.com","www.example.com","localhost"} {
    if !allowed[expected] { log.Printf("WARN: host %s not in AllowedHosts", expected) }
}

Try / catch

// Custom error handler to log rejected hosts for diagnosis
cfg.ErrorHandler = func(c fiber.Ctx, err error) error {
    log.Printf("hostauthorization rejected host: %q", c.Host())
    return c.SendStatus(fiber.StatusForbidden)
}

Prevention

When it happens

Trigger: Any request whose Host header is not in the allowlist: a direct-IP access when only domain names are allowed; a request to a staging domain on a production-configured app; a health-check from a load balancer using a raw IP; an attacker spoofing an arbitrary Host header. Also fires when parseNormalizedAuthority rejects malformed hosts (hostauthorization.go:292-294).

Common situations: Forgetting to list all domains the app is served under (apex + www, staging, internal); load balancer health checks using IP; accessing via localhost during development; adding a new domain alias without updating config; IDN domains not matching because of Punycode conversion differences.

Related errors


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