thanos-io/thanos · error · ApiError
tenant not found
Error message
%s tenant not found
What it means
When a `tenant` query param is provided, the response map from TSDBStatistics must contain an entry keyed by that tenant; if the map has no such key, this internal error (wrapped as '%s tenant not found') is returned.
Solutions
- Verify the tenant name matches exactly the tenant key reported in stats (case-sensitive).
- Drop the tenant param to get merged statistics from all tenants and inspect available tenant keys.
- Ensure the request reaches stores that actually hold the tenant's data (correct routing/sidecar/store-gateway config).
Example fix
// before GET /api/v1/tsdb/status?tenant=mytenant // store has "MyTenant" // after GET /api/v1/tsdb/status // inspect available tenants, then use exact key GET /api/v1/tsdb/status?tenant=MyTenant
Defensive patterns
Strategy: fallback
Try / catch
let data = await fetch(`${base}/api/v1/tsdb/status?tenant=${encodeURIComponent(tenant)}`).then(r => r.json());
if (data.status === 'error' && /tenant not found/.test(data.error)) {
// fall back to merged stats to discover valid tenant keys
data = await fetch(`${base}/api/v1/tsdb/status`).then(r => r.json());
} Prevention
- Fetch unfiltered stats once and cache the set of valid tenant keys.
- Validate tenant names against known tenants before querying.
- Remember tenant keys are case-sensitive and data-presence dependent.
When it happens
Trigger: GET /api/v1/tsdb/status?tenant=foo where no store returned statistics for tenant 'foo' — the tenant does not exist, has an empty TSDB, or the request was served by stores that don't own that tenant's data.
Common situations: Typo in tenant name; querying against stores/route paths of a different tenant (multi-tenant setups); tenant with no data at query time; hitting a Thanos receive/querier that doesn't serve that tenant.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- query-frontend.org-id-header and…
- invalid tenant ID
- limit overflows int32
- retrieving tsdb statistics
- meta.json bkt get for
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/506ed666a3a95132.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/api/query/v1.go:1767
}
req := &statuspb.TSDBStatisticsRequest{
Matchers: matchers,
Limit: int32(limit),
PartialResponseStrategy: ps,
}
var stats map[string]*statuspb.TSDBStatisticsEntry
tracing.DoInSpan(ctx, "retrieve_tsdb_statistics", func(ctx context.Context) {
stats, warnings, err = qapi.status.TSDBStatistics(ctx, req)
})
if err != nil {
return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(err, "retrieving tsdb statistics")}, func() {}
}
if tenant != "" {
if stats[tenant] == nil {
return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(fmt.Errorf("%s tenant not found", tenant), "retrieving tsdb statistics")}, func() {}
}
return convertToTSDBSTatus(stats[tenant], limit), warnings.AsErrors(), nil, func() {}
}
// Merge statistics from all tenants.
aggregatedStats := &statuspb.TSDBStatisticsEntry{}
for _, v := range stats {
aggregatedStats.Merge(v)
}
return convertToTSDBSTatus(aggregatedStats, limit), warnings.AsErrors(), nil, func() {}
}
func convertToTSDBSTatus(tsdbStatsEntry *statuspb.TSDBStatisticsEntry, limit int) *v1.TSDBStatus {
return &v1.TSDBStatus{
HeadStats: v1.HeadStats{
NumSeries: tsdbStatsEntry.HeadStatistics.NumSeries,View on GitHub (pinned to 35b8b99117)