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

  1. Verify the service is registered and healthy in the discovery backend (consul members/catalog, etcd keys, DNS SRV record)
  2. Use sd Retry with a backoff window so balancer.Endpoint() is re-attempted while discovery warms up
  3. Check the Instancer/subscriber construction: correct service name, datacenter, and a working SD client connection
  4. 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

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


AI-assisted analysis of go-kit/kit@78fbbceece (2026-08-15). Data as JSON: /api/errors/538e484258c8610a. Report an issue: GitHub.