gofiber/fiber · error

client cannot be nil

Error message

client cannot be nil

What it means

Has two failure modes. (1) PANIC: Request.SetClient(nil) panics with ErrClientNil (client/request.go:105) because a request without a client cannot execute. (2) RETURNED error: Response.JSON/CBOR/XML return ErrClientNil (client/response.go:158,167,176) when r.client == nil, because the (de)serialization function lives on the client and is unreachable.

Solutions

  1. Always pair Request with a non-nil Client: req := client.Get(); do not call req.SetClient(nil).
  2. After acquiring a Response from the pool, ensure setClient was called (the normal Do path does this in core.go:109).
  3. In tests, construct responses through the client or call the package-level acquire helper that sets the client.
  4. For Response.JSON/CBOR/XML, if you only have the body bytes, unmarshal them directly with the codec instead of going through resp.JSON().

Example fix

// before (panic)
req.SetClient(nil) // panic: ErrClientNil

// before (returned)
resp := acquireOrphanResponse()
err := resp.JSON(&v) // ErrClientNil

// after
req := client.Get().SetURL(u) // request keeps its client
resp, err := req.Send()
err = resp.JSON(&v) // client present
Defensive patterns

Strategy: validation

Validate before calling

func ensureClient(req *fiber.Request, c *fiber.Client) error {
    if c == nil { return fiber.ErrClientNil }
    req.SetClient(c)
    return nil
}

Type guard

func hasClient(r *fiber.Response) bool { return r != nil && r.Client() != nil }

Try / catch

if err := resp.JSON(&v); err != nil {
    if errors.Is(err, fiber.ErrClientNil) {
        // unmarshal the body directly with the codec instead
        err = json.Unmarshal(resp.Body(), &v)
    }
}

Prevention

When it happens

Trigger: Calling req.SetClient(nil); using a Response whose client was cleared (e.g. after Reset() or a pooled response reused without setClient); calling resp.JSON() on a Response acquired from a non-client source; unit tests that build a Response manually.

Common situations: Reusing a pooled Response after Reset() zeroed r.client; returning a Response from a goroutine that lost its client reference; test helpers that construct fiber.Response{} directly; refactoring that drops the SetClient call.

Related errors


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

Appendix: source

Thrown at client/request.go:42

	Add(name, obj string)
	Del(name string)
}

// bodyType defines the type of request body.
type bodyType int

// Enumeration of request body types.
const (
	noBody bodyType = iota
	jsonBody
	xmlBody
	formBody
	filesBody
	rawBody
	cborBody
)

var ErrClientNil = errors.New("client cannot be nil")

// Request contains all data related to an HTTP request.
type Request struct {
	ctx context.Context //nolint:containedctx // Context is needed to be stored in the request.

	body    any
	header  Header
	params  QueryParam
	cookies Cookie
	path    PathParam

	client *Client

	formData FormData

	RawRequest *fasthttp.Request
	url        string
	method     string

View on GitHub (pinned to a105acad6c)