valyala/fasthttp · error

fasthttp: no available clients

Error message

fasthttp: no available clients

What it means

LBClient balances requests across a set of BalancingClients. If that set is empty — typically because every client was removed via LBClient.RemoveClient or none were ever added — its Do/DoDeadline/DoTimeout methods return ErrNoAvailableClients instead of panicking or blocking.

Source

Thrown at lbclient.go:12

package fasthttp

import (
	"errors"
	"sync"
	"sync/atomic"
	"time"
)

// ErrNoAvailableClients is returned by LBClient methods when no clients are
// available, for example after every client has been removed.
var ErrNoAvailableClients = errors.New("fasthttp: no available clients")

// BalancingClient is the interface for clients, which may be passed
// to LBClient.Clients.
type BalancingClient interface {
	DoDeadline(req *Request, resp *Response, deadline time.Time) error
	PendingRequests() int
}

// LBClient balances requests among available LBClient.Clients.
//
// It has the following features:
//
//   - Balances load among available clients using 'least loaded' + 'least total'
//     hybrid technique.
//   - Dynamically decreases load on unhealthy clients.
//
// It is forbidden copying LBClient instances. Create new instances instead.
//

View on GitHub (pinned to c96f600972)

Solutions

  1. Ensure at least one BalancingClient is registered before serving traffic: lbClient.Clients = []fasthttp.BalancingClient{c1, c2}.
  2. Guard removal logic so the last healthy client is never removed (e.g. keep a minimum pool size or re-add on failure detection).
  3. Check the error and fall back to a default upstream or return 503 until discovery repopulates clients.

Example fix

// before
lb := &fasthttp.LBClient{}
lb.RemoveClient(c1)
err := lb.Do(req, resp) // fasthttp: no available clients
// after
lb := &fasthttp.LBClient{Clients: []fasthttp.BalancingClient{c1, c2}}
// never remove the last client:
if len(lb.Clients) > 1 { lb.RemoveClient(c2) }
err := lb.Do(req, resp)
Defensive patterns

Strategy: fallback

Validate before calling

if lbClient == nil || len(lbClient.Clients) == 0 {
    return errors.New("LBClient has no upstream clients configured")
}

Try / catch

err := lbClient.Do(req, resp)
if errors.Is(err, fasthttp.ErrNoAvailableClients) {
    return errNoUpstream // surface 503 / use fallback upstream
}

Prevention

When it happens

Trigger: Calling LBClient.Do/DoDeadline/DoTimeout after all clients have been removed (RemoveClient called for each), or constructing an LBClient with no Clients configured.

Common situations: Health-based removal logic that evicts all backends during an outage; misconfigured service discovery returning an empty backend list; tests constructing LBClient without clients.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/6d3d0f6b9fee6395. Report an issue: GitHub.