gofiber/fiber · warning
failed to resolve TCP address after adding port: %w
Error message
failed to resolve TCP address after adding port: %w
What it means
Returned by resolveRemoteAddr in adaptor.FiberHandler/http adapter when the upstream http.Server gave a RemoteAddr with no port, the code appended default port ':80', and the retry of net.ResolveTCPAddr still failed. This indicates the host portion itself is malformed or unresolvable, not merely missing a port. It is produced inside the per-request handler, so the error is logged and remoteAddr falls back to nil rather than crashing the request.
Source
Thrown at middleware/adaptor/adaptor.go:456
return newTCPAddr(a[:], port, ip.Zone()), nil
}
}
}
resolved, err := net.ResolveTCPAddr("tcp", remoteAddr)
if err == nil {
return resolved, nil
}
var addrErr *net.AddrError
if errors.As(err, &addrErr) && addrErr != nil && addrErr.Err == "missing port in address" {
if len(remoteAddr) > 253 { // Max hostname length
return nil, ErrRemoteAddrTooLong
}
remoteAddr = net.JoinHostPort(remoteAddr, "80")
resolved, err2 := net.ResolveTCPAddr("tcp", remoteAddr)
if err2 != nil {
return nil, fmt.Errorf("failed to resolve TCP address after adding port: %w", err2)
}
return resolved, nil
}
return nil, fmt.Errorf("failed to resolve TCP address: %w", err)
}
func handlerFunc(app *fiber.App, h ...fiber.Handler) http.HandlerFunc {
// App.Config returns the config by value, so read the body limit once at
// construction instead of copying the whole 624-byte struct on every
// request. Fiber only writes app.config in New. The error handler is
// deliberately not cached: App.ErrorHandler resolves a mounted sub-app's
// handler from the request path, and that lookup belongs per request.
maxBodySize := int64(app.Config().BodyLimit)
return func(w http.ResponseWriter, r *http.Request) {
// New fasthttp Ctx from pool
pctx := ctxPool.Get().(*pooledCtx) //nolint:forcetypeassert,errcheck // not needed
fctx := &pctx.fctxView on GitHub (pinned to 9a4c7e57fe)
Solutions
- Inspect what r.RemoteAddr actually contains at the adapter boundary (log it once) and fix the upstream that sets it.
- Configure your proxy/LB to always send host:port in RemoteAddr (nginx 'proxy_set_header' / ELB proxy protocol).
- If you control the caller, pass net.JoinHostPort(host, '80') explicitly so ResolveTCPAddr never sees a portless address.
- Strip invalid characters from X-Forwarded-For before it reaches the Go http stack, or use trusted proxy hop parsing.
Example fix
// before: upstream hands a bare hostname, resolve fails
// r.RemoteAddr == "frontend.local"
// after: nginx always emits host:port
// proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
// and on the Go side, normalize defensively:
host, port, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
r.RemoteAddr = net.JoinHostPort(strings.TrimSpace(r.RemoteAddr), "80")
} Defensive patterns
Strategy: validation
Validate before calling
// Normalize an upstream RemoteAddr to host:port before passing into adaptor.
func normalizeRemoteAddr(addr string) string {
if addr == "" {
return ""
}
if _, _, err := net.SplitHostPort(addr); err == nil {
return addr // already has port
}
// bare host or IP -> append default http port
return net.JoinHostPort(strings.TrimSpace(addr), "80")
} Type guard
null
Try / catch
null
Prevention
- Configure upstream proxies to always send host:port in RemoteAddr.
- Reject/drop malformed X-Forwarded-For at the trust boundary.
- Use net.JoinHostPort instead of string concatenation to build addresses.
- Log r.RemoteAddr once at the adapter edge to catch upstream regressions.
When it happens
Trigger: Wrapping a fiber.App with adaptor.FiberApp and having a reverse proxy/proxy chain populate RemoteAddr with a bare hostname, an IP with garbage trailing characters, or a hostname longer than 253 chars that escaped the earlier guard. X-Forwarded-For values containing invalid IPs that get assigned to r.RemoteAddr by a misbehaving upstream also trigger it.
Common situations: Load balancer sends 'X-Forwarded-For' with a malformed value that a proxy set verbatim into RemoteAddr; IPv6 link-local address with zone but no port; testing with a stub http.Server whose RemoteAddr is a hostname only; upgrading a proxy that previously appended ':80' to no longer doing so.
Related errors
- failed to resolve TCP address: %w
- remote address cannot be empty
- proxy: upstream host resolves to a blocked address
- client: invalid proxy URL: %w
- range: unsatisfiable range
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/f91f0ab2ab6a79ac.json.
Report an issue: GitHub.