thanos-io/thanos · error
shuffle sharding requires ketama hashring as base ring
Error message
shuffle sharding requires ketama hashring as base ring
What it means
shuffleShardHashring.getTenantShard asserts its base ring is a *ketamaHashring; when the underlying implementation is anything else (e.g. a simple hashring) this error is returned. Shuffle sharding is only implemented on top of the ketama consistent-hashing ring, so this is a programming/configuration invariant violation.
Solutions
- Build the base ring with newKetamaHashring before wrapping it with newShuffleShardHashring
- Use the Ketama algorithm in config when shuffleSharding.shardSize > 0 (the hashmod path already rejects it)
- Audit custom code that constructs hashrings directly and fix the type passed as baseRing
Example fix
// before base := newSimpleHashring(endpoints) shard := newShuffleShardHashring(base, cfg, rf, reg, name) // after base := newKetamaHashring(endpoints, SectionsPerNode, replicationFactor) shard := newShuffleShardHashring(base, cfg, rf, reg, name)
Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := baseRing.(*ketamaHashring); !ok {
return fmt.Errorf("shuffle sharding requires a ketama base ring")
} Type guard
base, ok := ring.(*ketamaHashring)
if !ok {
return nil, errors.New("shuffle sharding requires ketama hashring as base ring")
} Try / catch
shard, err := ssRing.GetTenantShard(tenant)
if err != nil {
return Endpoint{}, fmt.Errorf("tenant shard unavailable: %w", err)
} Prevention
- Only wrap ketama rings with newShuffleShardHashring
- Route through newHashringConfig instead of constructing rings manually
When it happens
Trigger: Constructing a shuffle-shard hashring with a base ring that is not a ketama hashring — e.g. wiring a simple hashring as the base, or a code path that built the ring with the wrong algorithm before wrapping it with newShuffleShardHashring.
Common situations: Custom code embedding the hashring package passes a newSimpleHashring where ketama is required; refactors change the ring type but not the shuffle-shard wrapper.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- shard size is larger than number of nodes in AZ ( )
- hashmod algorithm does not support shuffle sharding. Either…
- shard size is larger than number of nodes in hashring ( )
- retrieving targets
- error retrieving rules
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/63c1d176cdea9531.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/receive/hashring.go:603
}
h, err := s.getTenantShard(tenant)
if err != nil {
return nil, err
}
s.metrics.numItems.Inc()
s.cache.Add(tenant, h)
return h, nil
}
// getTenantShard returns a consistent subset of nodes for a tenant using
// Cortex-style consistent hashing.
func (s *shuffleShardHashring) getTenantShard(tenant string) (*ketamaHashring, error) {
baseRing, ok := s.baseRing.(*ketamaHashring)
if !ok {
return nil, fmt.Errorf("shuffle sharding requires ketama hashring as base ring")
}
nodes := s.Nodes()
nodesByAZ := make(map[string][]Endpoint)
for _, node := range nodes {
var az = node.AZ
if s.shuffleShardingConfig.ZoneAwarenessDisabled {
az = ""
}
nodesByAZ[az] = append(nodesByAZ[az], node)
}
sectionsByAZ := make(map[string]sections)
for _, sec := range baseRing.sections {
endpoint := baseRing.endpoints[sec.endpointIndex]
var az = endpoint.AZ
if s.shuffleShardingConfig.ZoneAwarenessDisabled {
az = ""View on GitHub (pinned to 35b8b99117)