thanos-io/thanos · error
no matching hashring to handle tenant
Error message
no matching hashring to handle tenant
What it means
multiHashring.GetN (via Get) failed to find any hashring in the multihashing configuration whose tenant list covers the requested tenant, so it returns this error and an empty Endpoint. It means the receive configuration partitions tenants across hashrings but the given tenant falls into no partition.
Solutions
- Add the tenant to the appropriate hashring's tenants list (or a catch-all '*' glob hashring) in the receive configuration
- Verify the exact tenant string sent by clients matches config casing/labels
- Ensure all receiver nodes share the same hashring config to avoid inconsistent routing
- If a default hashring is desired, add a final hashring with tenants: ['.*' or '*'] depending on matcher type
Example fix
// before
hashrings:
- hashring: shard-0
tenants: [tenant-a]
// after
hashrings:
- hashring: shard-0
tenants: [tenant-a]
- hashring: default
tenants: ['*'] Defensive patterns
Strategy: try-catch
Validate before calling
func tenantCovered(tenant string, rings []HashringConfig) bool {
for _, r := range rings {
for _, t := range r.Tenants {
ok, _ := matchTenant(t, tenant)
if ok { return true }
}
}
return false
} Try / catch
endpoint, err := hashring.Get(tenant)
if errors.Is(err, errNoMatchingHashring) {
log.Warn("tenant not in any hashring, using default", "tenant", tenant)
endpoint = fallbackEndpoint
} Prevention
- Always include a catch-all hashring for unknown tenants
- Keep tenant lists in sync with allowed tenants (single source of config)
- Distribute identical hashring config to all receivers
- Alert on this error to catch config drift early
When it happens
Trigger: Calling Hasher/multiHashring Get/GetN with a tenant that matches none of the configured hashrings' tenant lists (each hashring matched via hashmod/glob/exact matchers).
Common situations: A tenant was created after the hashring config was written; tenant name typo in requests; tenants list intentionally excludes the tenant but the client still routes writes to it; config mismatch between querier and receiver.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- configuration file is not parsable
- configuration file is empty
- endpoint address must be set
- failed to read configuration file
- failed to load configuration file, path
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/67cedd185314bba1.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/receive/hashring.go:345
if mt, ok := t[tenant]; ok && isExactMatcher(mt) {
found = true
} else {
var err error
if found, err = t.match(tenant); err != nil {
return Endpoint{}, err
}
}
}
if found {
m.mu.Lock()
m.cache[tenant] = m.hashrings[i]
m.mu.Unlock()
return m.hashrings[i].GetN(tenant, ts, n)
}
}
return Endpoint{}, errors.New("no matching hashring to handle tenant")
}
func (m *multiHashring) Nodes() []Endpoint {
return m.nodes
}
// shuffleShardHashring wraps a hashring implementation and applies shuffle sharding logic
// to limit which nodes are used for each tenant.
type shuffleShardHashring struct {
baseRing Hashring
shuffleShardingConfig ShuffleShardingConfig
replicationFactor uint64
nodes []Endpoint
cache *lru.Cache[string, *ketamaHashring]View on GitHub (pinned to 35b8b99117)