gofiber/fiber · error · errNilProxyClientOverride
proxy: nil client override passed to Do/Forward
Error message
proxy: nil client override passed to Do/Forward
What it means
Returned by proxy.selectClient (proxy.go:144, 546) when Do/Forward/DoRedirects is called with a variadic client override argument whose first element is nil. selectClient resolves which *fasthttp.Client to use: if clients are passed, it uses clients[0], but if that is nil it returns this error rather than panicking on a nil dereference. This is an unexported error (lowercase) returned to the caller of Do/Forward.
Source
Thrown at middleware/proxy/proxy.go:144
return err
}
}
// Return nil to end proxying if no error
return nil
}
}
var defaultClient = &fasthttp.Client{
NoDefaultUserAgentHeader: true,
DisablePathNormalizing: true,
MaxConnsPerHost: defaultMaxConnsPerHost,
}
var client atomic.Pointer[fasthttp.Client]
var (
errNilProxyClientOverride = errors.New("proxy: nil client override passed to Do/Forward")
errNilGlobalProxyClient = errors.New("proxy: global client is nil, set a non-nil client with proxy.WithClient")
)
// guardedConfigureClient composes a client's optional pre-existing
// ConfigureClient hook with the dial-time SSRF guard. It is installed on a
// *fasthttp.Client as the bound method value (&guardedConfigureClient{…}).run,
// which fasthttp calls once per HostClient it creates — so the guard is
// present before the first dial to each host and covers both the Dial and
// DialTimeout code paths.
//
// The bound method's code pointer is stable across receivers (unlike a
// closure's), so ensureClientGuarded recognizes an already-guarded client by
// identity — no package-level map keyed by the client, which would pin the
// client and its connection pool for the process lifetime. The struct is
// referenced only from the client's own ConfigureClient field, so it is
// collected together with the client.
type guardedConfigureClient struct {
// orig is the caller's ConfigureClient hook, or nil. It runs before theView on GitHub (pinned to 9a4c7e57fe)
Solutions
- Do not pass a nil client — if you have no custom client, call Do/Forward without the clients argument so the global default client is used.
- Ensure any client variable is initialized before being passed.
- If conditionally using a custom client, branch: call Do with the client when set, and without when not.
Example fix
// before
var cli *fasthttp.Client
if useCustom { cli = customClient }
proxy.Do(c, target, cli) // cli may be nil
// after
if cli != nil {
proxy.Do(c, target, cli)
} else {
proxy.Do(c, target) // uses global default client
} Defensive patterns
Strategy: validation
Validate before calling
// Never pass a nil client; branch instead
if customClient != nil {
return proxy.Do(c, target, customClient)
}
return proxy.Do(c, target) // use global default Prevention
- Only pass the variadic client argument when you have a non-nil client.
- Initialize client variables before use.
- Code-review proxy call sites for conditional client passing.
When it happens
Trigger: Calling proxy.Do(c, url, nil) or proxy.Forward(addr, nilClient) — explicitly passing a nil *fasthttp.Client as the optional override. This is a programmer error in the calling code, not a runtime/config issue.
Common situations: Conditionally building a client and passing it even when the condition didn't set it (var cli *fasthttp.Client; ...; proxy.Do(c, url, cli)); refactoring that leaves a nil where a client was expected; testing code that passes nil as a placeholder.
Related errors
- proxy: upstream scheme is not allowed
- proxy: upstream host is empty or invalid
- client: invalid proxy URL: %w
- proxy: parse upstream %q: %w
- ErrUpstreamHostBlocked
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/b3e72598fce9de0d.json.
Report an issue: GitHub.