gofiber/fiber · critical · ErrUpstreamHostInvalid
proxy: upstream host is empty or invalid
Error message
proxy: upstream host is empty or invalid
What it means
Returned by proxy.parseUpstream/parseUpstreamScheme (security.go:54, 290, 334) and validateHostForSSRF when the upstream URL has an empty host (e.g. 'http://:8080' where Hostname() is empty) or the raw upstream string is empty/whitespace. The proxy requires a concrete hostname to dial; an empty host is both a misconfiguration and an SSRF risk. Fires per-request for Do/Forward and as a startup panic for DomainForward/BalancerForward.
Source
Thrown at middleware/proxy/security.go:54
// SecurityPolicy.AllowedSchemes field, so nothing outside this file can
// mutate the backing array.
var defaultAllowedSchemes = []string{schemeHTTP, schemeHTTPS}
// httpsSchemeBytes is the byte form of "https" used by redirect
// downgrade checks. Stored once so the resolveRedirect hot path doesn't
// allocate []byte("https") on every hop.
var httpsSchemeBytes = []byte(schemeHTTPS)
// Sentinel errors returned when an upstream target violates the configured
// proxy security policy.
var (
// ErrUpstreamSchemeNotAllowed is returned when the proxied URL uses a
// scheme outside the configured allowlist (default: http, https).
ErrUpstreamSchemeNotAllowed = errors.New("proxy: upstream scheme is not allowed")
// ErrUpstreamHostInvalid is returned when the proxied URL is missing a
// host or cannot be parsed.
ErrUpstreamHostInvalid = errors.New("proxy: upstream host is empty or invalid")
// ErrUpstreamHostBlocked is returned when the proxied URL resolves to
// an address inside a blocked range (loopback, RFC 1918 private,
// link-local, multicast, unspecified, or CGNAT) and AllowPrivateIPs
// is false.
ErrUpstreamHostBlocked = errors.New("proxy: upstream host resolves to a blocked address")
// ErrRedirectDowngrade is returned when DoRedirects encounters a
// redirect from an HTTPS upstream to a plaintext HTTP target and
// AllowHTTPSDowngrade is false.
ErrRedirectDowngrade = errors.New("proxy: HTTPS to HTTP redirect blocked")
)
// SecurityPolicy controls runtime security restrictions applied to the
// proxy.Do, proxy.Forward, proxy.DoRedirects, proxy.DoTimeout, and
// proxy.DoDeadline runtime helpers as well as Balancer instances that
// do not supply their own policy via Config.SecurityPolicy.
type SecurityPolicy struct {View on GitHub (pinned to 9a4c7e57fe)
Solutions
- Ensure the upstream URL includes a non-empty hostname or IP (e.g. 'http://backend:8080').
- Validate the upstream string is non-empty before passing it to proxy functions.
- For env-driven upstreams, fail fast at startup if the env var is empty rather than per-request.
Example fix
// before
upstream := os.Getenv("UPSTREAM_URL") // may be empty
proxy.Do(c, upstream)
// after
upstream := os.Getenv("UPSTREAM_URL")
if upstream == "" {
return c.SendStatus(fiber.StatusBadGateway)
}
proxy.Do(c, upstream) Defensive patterns
Strategy: validation
Validate before calling
// Validate upstream host is non-empty before proxying
u, err := url.Parse(upstream)
if err != nil || u.Hostname() == "" {
return c.Status(fiber.StatusBadGateway).SendString("invalid upstream")
}
return proxy.Do(c, upstream) Prevention
- Fail fast at startup if env-driven upstream URLs are empty.
- Validate dynamically-built upstreams include a host component.
- Log the upstream string on proxy errors to catch empty-host bugs.
When it happens
Trigger: Passing an empty string or whitespace to proxy.Do/Forward; configuring an upstream like 'http://:8080' (port but no host); a URL like 'http:///path' (empty host); or a dynamically-built upstream where the host variable is unset. validateHostForSSRF (security.go:390) also returns it when the resolved host is empty.
Common situations: Environment variable for the upstream host is unset (empty string); templated upstream URL with a missing variable; copy-paste error dropping the hostname; upstream built from request input where the host part is absent; IPv6 URL missing brackets.
Related errors
- proxy: upstream scheme is not allowed
- ErrUpstreamHostBlocked
- logger: tag name and function are required
- proxy: nil client override passed to Do/Forward
- proxy: upstream host resolves to a blocked address
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/e3b7c5cbf12288f2.json.
Report an issue: GitHub.