{"record":{"id":"67cedd185314bba1","repo":"thanos-io/thanos","slug":"no-matching-hashring-to-handle-tenant","errorCode":null,"errorMessage":"no matching hashring to handle tenant","messagePattern":"no matching hashring to handle tenant","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/receive/hashring.go","lineNumber":345,"sourceCode":"\t\t\tif mt, ok := t[tenant]; ok && isExactMatcher(mt) {\n\t\t\t\tfound = true\n\t\t\t} else {\n\t\t\t\tvar err error\n\t\t\t\tif found, err = t.match(tenant); err != nil {\n\t\t\t\t\treturn Endpoint{}, err\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t\tif found {\n\t\t\tm.mu.Lock()\n\t\t\tm.cache[tenant] = m.hashrings[i]\n\t\t\tm.mu.Unlock()\n\n\t\t\treturn m.hashrings[i].GetN(tenant, ts, n)\n\t\t}\n\t}\n\treturn Endpoint{}, errors.New(\"no matching hashring to handle tenant\")\n}\n\nfunc (m *multiHashring) Nodes() []Endpoint {\n\treturn m.nodes\n}\n\n// shuffleShardHashring wraps a hashring implementation and applies shuffle sharding logic\n// to limit which nodes are used for each tenant.\ntype shuffleShardHashring struct {\n\tbaseRing Hashring\n\n\tshuffleShardingConfig ShuffleShardingConfig\n\n\treplicationFactor uint64\n\n\tnodes []Endpoint\n\n\tcache *lru.Cache[string, *ketamaHashring]","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/hashring.go#L327-L363","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nhashrings:\n  - hashring: shard-0\n    tenants: [tenant-a]\n// after\nhashrings:\n  - hashring: shard-0\n    tenants: [tenant-a]\n  - hashring: default\n    tenants: ['*']","handlingStrategy":"try-catch","validationCode":"func tenantCovered(tenant string, rings []HashringConfig) bool {\n    for _, r := range rings {\n        for _, t := range r.Tenants {\n            ok, _ := matchTenant(t, tenant)\n            if ok { return true }\n        }\n    }\n    return false\n}","typeGuard":null,"tryCatchPattern":"endpoint, err := hashring.Get(tenant)\nif errors.Is(err, errNoMatchingHashring) {\n    log.Warn(\"tenant not in any hashring, using default\", \"tenant\", tenant)\n    endpoint = fallbackEndpoint\n}","preventionTips":["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"],"tags":["hashring","tenant-routing","config"],"backgroundTag":"resource-not-found","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}