gofiber/fiber · critical

fasthttp.HostClient must not be nil

Error message

fasthttp.HostClient must not be nil

What it means

NewWithHostClient wraps a *fasthttp.HostClient (single-host client) into a Fiber client. A nil HostClient would crash on first request, so the constructor panics at construction time. Prefer this over NewWithClient when you talk to one host and want connection reuse tuning.

Solutions

  1. Construct the HostClient explicitly: &fasthttp.HostClient{Addr: "example.com:443"} and pass it non-nil.
  2. Check the error from any builder helper before passing its result.
  3. Default to fiber.New() when the host is unknown.

Example fix

// before
hc, _ := buildHostClient(cfg) // ignored error, hc is nil
client := fiber.NewWithHostClient(hc)

// after
hc, err := buildHostClient(cfg)
if err != nil { return err }
client := fiber.NewWithHostClient(hc)
Defensive patterns

Strategy: validation

Validate before calling

func newWithHostClientSafe(c *fasthttp.HostClient) (*fiber.Client, error) {
    if c == nil { return nil, errors.New("HostClient is nil") }
    return fiber.NewWithHostClient(c), nil
}

Try / catch

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

Prevention

When it happens

Trigger: Calling fiber.NewWithHostClient(nil) or passing a *fasthttp.HostClient that was conditionally constructed and ended up nil.

Common situations: Building the HostClient from config where the config block was empty; helper that returns (*HostClient, error) where the error was ignored and the pointer is nil; runtime env missing the host setting.

Related errors


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

Appendix: source

Thrown at client/client.go:944

func New() *Client {
	// Follow-up performance optimizations:
	// Try to use a pool to reduce the memory allocation cost for the Fiber client and the fasthttp client.
	// If possible, also consider pooling other structs (e.g., request headers, cookies, query parameters, path parameters).
	return NewWithClient(&fasthttp.Client{})
}

// NewWithClient creates and returns a new Client object from an existing fasthttp.Client.
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{},
		},

View on GitHub (pinned to a105acad6c)