go-kit/kit · error · ErrNoEndpoints
no endpoints available
Error message
no endpoints available
What it means
Declared in sd/lb/balancer.go and returned by the RoundRobin (round_robin.go:29) and Random (random.go:29) balancers when the sd.Endpointer yields an empty endpoint slice: service discovery currently knows zero qualifying instances for the target service. The balancer has nothing to hand out, so Retry/RPC code that called balancer.Endpoint() gets this error instead of an endpoint.
Source
Thrown at sd/lb/balancer.go:15
package lb
import (
"errors"
"github.com/go-kit/kit/endpoint"
)
// Balancer yields endpoints according to some heuristic.
type Balancer interface {
Endpoint() (endpoint.Endpoint, error)
}
// ErrNoEndpoints is returned when no qualifying endpoints are available.
var ErrNoEndpoints = errors.New("no endpoints available")
View on GitHub (pinned to 78fbbceece)
Solutions
- Verify the service is registered and healthy in the discovery backend (consul members/catalog, etcd keys, DNS SRV record)
- Use sd Retry with a backoff window so balancer.Endpoint() is re-attempted while discovery warms up
- Check the Instancer/subscriber construction: correct service name, datacenter, and a working SD client connection
- Expose the error as HTTP 503 (not 500) so callers and LBs treat it as temporary
Example fix
// before: single call, fails on cold start
ep, err := lb.NewRoundRobin(subscriber).Endpoint()
if err != nil {
return err // lb.ErrNoEndpoints
}
// after: brief bounded retry while discovery populates
var ep endpoint.Endpoint
for i := 0; i < 5; i++ {
ep, err = balancer.Endpoint()
if err == nil {
break
}
if !errors.Is(err, lb.ErrNoEndpoints) {
return err
}
time.Sleep(200 * time.Millisecond)
} Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
ep, err := balancer.Endpoint()
if err != nil {
if !errors.Is(err, lb.ErrNoEndpoints) {
return err // different failure, propagate
}
// discovery is empty: bounded retry with backoff, then surface as 503
if err := retryWithBackoff(ctx, 5, 300*time.Millisecond, func() error {
ep, err = balancer.Endpoint()
return err
}); err != nil {
return err
}
} Prevention
- Delay consumer readiness until the Instancer has received its first discovery update (liveness/readiness probes)
- Wrap balancer.Endpoint() in sd/lb Retry so transient empty pools are retried automatically
- Monitor the subscriber's endpoint count; alert when it drops to zero
- Return 503 (not 500) for ErrNoEndpoints so upstream LBs and clients back off correctly
When it happens
Trigger: The service deregistered from (or never registered in) consul/etcd/zookeeper/dnssrv; the Instancer subscriber hasn't received its first update yet (startup race); all instances failed their health check and were pruned; the subscriber lost its connection to the discovery backend so its cache went empty; wrong service name queried.
Common situations: Cold start: consumer boots before any producer registers; discovery backend outage or credentials expiry; k8s scale-to-zero then a request arrives before scale-up; environment misconfiguration (wrong namespace/datacenter in the SD client); all endpoints marked unhealthy after a deploy gone wrong.
Related errors
- CasbinModel is required in context
- CasbinPolicy is required in context
- Unauthorized Access
- token up for parsing was not passed through the context
- JWT was invalid
AI-assisted analysis of go-kit/kit@78fbbceece (2026-08-15).
Data as JSON: /api/errors/538e484258c8610a.
Report an issue: GitHub.