thanos-io/thanos · error

ketama: amount of endpoints needs to be larger than…

Error message

ketama: amount of endpoints needs to be larger than replication factor

What it means

newKetamaHashring validates that the number of ring endpoints is at least the replication factor, since each series must be written to that many distinct nodes on the ring. With fewer endpoints than the replication factor, AZ-aware or replicated assignment is impossible, so construction fails with this error.

Solutions

  1. Add more endpoints to the hashring so the count is >= replication factor.
  2. Lower the replication factor in the receive configuration to be <= number of endpoints.
  3. Fix tenant shard config (Shard/Hashring splits) so each shard retains at least replicationFactor endpoints.
  4. Verify the hashring file deployed to all nodes lists all running receive nodes.

Example fix

# before: 1 endpoint, replicationFactor 3
replicationFactor: 3
endpoints:
  - address: 127.0.0.1:10901
# after: add endpoints
endpoints:
  - address: 127.0.0.1:10901
  - address: 127.0.0.2:10901
  - address: 127.0.0.3:10901
Defensive patterns

Strategy: validation

Validate before calling

func validateKetama(cfg HashringConfig, rf uint64) error {
  if uint64(len(cfg.Endpoints)) < rf {
    return fmt.Errorf("need >= %d endpoints, have %d", rf, len(cfg.Endpoints))
  }
  return nil
}

Type guard

func ketamaViable(n int, rf uint64) bool { return uint64(n) >= rf }

Try / catch

hr, err := newKetamaHashring(eps, sections, rf); if err != nil { return nil, fmt.Errorf("ketama init: %w", err) }

Prevention

When it happens

Trigger: Building a ketama hashring where len(endpoints) < replicationFactor, e.g. 1 endpoint with replicationFactor 3, typically via getTenantShard/newHashring from the hashring config.

Common situations: Testing with a single receive node while replication factor is still 3; sharding a tenant to a small subset of endpoints smaller than the global replication factor; partially failed config rollout leaving fewer endpoints.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/9042c7ef07f01881. Report an issue: GitHub.

Appendix: source

Thrown at pkg/receive/hashring.go:153

func (p sections) Len() int           { return len(p) }
func (p sections) Less(i, j int) bool { return p[i].hash < p[j].hash }
func (p sections) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p sections) Sort()              { sort.Sort(p) }

// ketamaHashring represents a group of nodes handling write requests with consistent hashing.
type ketamaHashring struct {
	endpoints    []Endpoint
	sections     sections
	numEndpoints uint64
}

func (s ketamaHashring) Close() {}

func newKetamaHashring(endpoints []Endpoint, sectionsPerNode int, replicationFactor uint64) (*ketamaHashring, error) {
	numSections := len(endpoints) * sectionsPerNode

	if len(endpoints) < int(replicationFactor) {
		return nil, errors.New("ketama: amount of endpoints needs to be larger than replication factor")

	}
	hash := xxhash.New()
	availabilityZones := make(map[string]struct{})
	ringSections := make(sections, 0, numSections)

	for endpointIndex, endpoint := range endpoints {
		availabilityZones[endpoint.AZ] = struct{}{}
		for i := 1; i <= sectionsPerNode; i++ {
			_, _ = hash.Write([]byte(endpoint.Address + ":" + strconv.Itoa(i)))
			n := &section{
				az:            endpoint.AZ,
				endpointIndex: uint64(endpointIndex),
				hash:          hash.Sum64(),
				replicas:      make([]uint64, 0, replicationFactor),
			}

			ringSections = append(ringSections, n)

View on GitHub (pinned to 35b8b99117)