gofiber/fiber · critical

fasthttp.LBClient must not be nil

Error message

fasthttp.LBClient must not be nil

What it means

NewWithLBClient wraps a *fasthttp.LBClient (load-balancing client across multiple hosts). Passing nil panics immediately because the LB client is the transport core. Use this when you need client-side balancing across several backends.

Solutions

  1. Build the LBClient with at least one backend: &fasthttp.LBClient{Clients: []*fasthttp.HostClient{...}}.
  2. Guard against empty backend lists and fall back to NewWithHostClient or New().
  3. Validate backend config before constructing the client.

Example fix

// before
lb := buildLBClient(cfg.Backends) // returns nil when Backends empty
client := fiber.NewWithLBClient(lb)

// after
if len(cfg.Backends) == 0 { return errors.New("no backends") }
client := fiber.NewWithLBClient(buildLBClient(cfg.Backends))
Defensive patterns

Strategy: validation

Validate before calling

func newWithLBClientSafe(c *fasthttp.LBClient) (*fiber.Client, error) {
    if c == nil { return nil, errors.New("LBClient is nil") }
    return fiber.NewWithLBClient(c), nil
}

Try / catch

func safeNewWithLBClient(c *fasthttp.LBClient) (cl *fiber.Client, err error) {
    defer func() {
        if r := recover(); r != nil { err = fmt.Errorf("%v", r) }
    }()
    cl = fiber.NewWithLBClient(c)
    return cl, nil
}

Prevention

When it happens

Trigger: Calling fiber.NewWithLBClient(nil), or passing an LBClient built from an empty backend list helper that returned nil.

Common situations: Configuring backends from an env var that was empty; refactor that replaced a multi-host setup with a helper returning nil on zero backends; testing stub that forgot to populate the client.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/12fe11a4c0591759. Report an issue: GitHub.

Appendix: 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 a105acad6c)