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.fctx

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Inspect what r.RemoteAddr actually contains at the adapter boundary (log it once) and fix the upstream that sets it.
  2. Configure your proxy/LB to always send host:port in RemoteAddr (nginx 'proxy_set_header' / ELB proxy protocol).
  3. If you control the caller, pass net.JoinHostPort(host, '80') explicitly so ResolveTCPAddr never sees a portless address.
  4. 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

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


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