gofiber/fiber · error

fasthttp.LBClient must not be nil

Error message

fasthttp.LBClient must not be nil

What it means

Panics from client/client.go:952 inside NewWithLBClient when the supplied *fasthttp.LBClient is nil. An LBClient is fasthttp's client-side load balancer over multiple backends; a nil one cannot dial or rotate backends, so fiber refuses to build a client on top of it. As with the other transport constructors, this is a fail-fast guard for a nil transport.

Source

Thrown at client/client.go:952

func NewWithClient(c *fasthttp.Client) *Client {
	if c == nil {
		panic("fasthttp.Client must not be nil")
	}
	return newClient(newStandardClientTransport(c))
}

// NewWithHostClient creates and returns a new Client object from an existing fasthttp.HostClient.
func NewWithHostClient(c *fasthttp.HostClient) *Client {
	if c == nil {
		panic("fasthttp.HostClient must not be nil")
	}
	return newClient(newHostClientTransport(c))
}

// NewWithLBClient creates and returns a new Client object from an existing fasthttp.LBClient.
func NewWithLBClient(c *fasthttp.LBClient) *Client {
	if c == nil {
		panic("fasthttp.LBClient must not be nil")
	}
	return newClient(newLBClientTransport(c))
}

func newClient(transport httpClientTransport) *Client {
	return &Client{
		transport: transport,
		header: &Header{
			RequestHeader: &fasthttp.RequestHeader{},
		},
		params: &QueryParam{
			Args: fasthttp.AcquireArgs(),
		},
		cookies: &Cookie{},
		path:    &PathParam{},

		userRequestHooks:     []RequestHook{},
		builtinRequestHooks:  []RequestHook{parserRequestURL, parserRequestHeader, parserRequestBody},

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Allocate the LBClient and populate its Clients before passing it: client.NewWithLBClient(&fasthttp.LBClient{Clients: clients, Timeout: 5*time.Second}).
  2. If backend discovery can legitimately yield nothing, short-circuit with client.New() or skip client creation and log the empty-backend condition.
  3. Initialize the LBClient pointer in the same function that builds the fiber client so they cannot get out of sync.

Example fix

// before
app := client.NewWithLBClient(lb) // lb may be nil

// after
if lb == nil || len(lb.Clients) == 0 {
    return fmt.Errorf("no backends configured")
}
app := client.NewWithLBClient(lb)
Defensive patterns

Strategy: validation

Validate before calling

if lb == nil || len(lb.Clients) == 0 {
    return fmt.Errorf("LBClient not configured with backends")
}
app := client.NewWithLBClient(lb)

Type guard

func isLBClientReady(c *fasthttp.LBClient) bool {
    return c != nil && len(c.Clients) > 0
}

Prevention

When it happens

Trigger: Calling client.NewWithLBClient(nil), or passing an LBClient whose .Clients field was never populated (the struct itself non-nil is fine, but a nil pointer is not). Common when the LBClient is built from a config-driven list of backends that happened to be empty and the variable stayed nil.

Common situations: Dynamic backend discovery that returns no backends and leaves the LBClient pointer unset; shared/global LBClient initialized in an init() that ran after the client was constructed; tests that pass nil to skip real load balancing.

Related errors


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