thanos-io/thanos · error
cannot obtain metadata: neither info nor store client found
Error message
cannot obtain metadata: neither info nor store client found
What it means
In pkg/query EndpointSet metadata collection, after trying the /metadata endpoint and gRPC store-info paths, the code returns errors.New(noMetadataEndpointMessage) — "cannot obtain metadata: neither info nor store client found" — when an endpoint provides neither a StoreClient (gRPC store API) nor a working HTTP metadata endpoint. updateEndpoint records this as the endpoint's lastError.
Solutions
- Ensure each endpoint in the endpointset actually exposes a Thanos StoreAPI (gRPC) or a valid Thanos HTTP metadata endpoint.
- Upgrade sidecar/store components to a version that serves the StoreAPI (/store API or storepb).
- Verify endpoint addressing and paths; curl the /metadata endpoint to confirm it responds.
- Remove or fix endpoints that are not Thanos store nodes from the endpoint configuration.
Example fix
// before
// endpoint registered with only an HTTP address, no store API
EndpointSet{ Endpoints: []string{"http://prometheus:9090"} }
// after
// register the Thanos Sidecar StoreAPI gRPC endpoint instead
EndpointSet{ Endpoints: []string{"sidecar.example:10901"} } Defensive patterns
Strategy: validation
Validate before calling
// before adding an endpoint, verify it serves metadata or store API
resp, err := http.Get(endpointURL + "/metadata")
if err != nil || resp.StatusCode != http.StatusOK {
return fmt.Errorf("endpoint %s lacks metadata endpoint; ensure it exposes Thanos StoreAPI", endpointURL)
} Prevention
- Register only Thanos components exposing StoreAPI or /metadata in endpoint sets
- Check component versions support the StoreAPI before wiring
- Verify endpoint addresses resolve to Thanos sidecars/queriers, not plain Prometheus
When it happens
Trigger: Endpoint is registered in the EndpointSet but the gRPC StoreClient is unavailable (spec has no store API support) and the HTTP /metadata or /-/ endpoints fail or are absent (e.g. non-Thanos HTTP endpoint, or Sidecar/O storeAPI nil).
Common situations: Adding an HTTP-only endpoint (e.g. plain Prometheus URL without Thanos storeAPI); sidecar version too old to expose StoreAPI; endpoint URL typed wrong so /metadata 404s; mixing node types in --endpoint flag.
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
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/a80edc79b7a7c55a.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/query/endpointset.go:90
func (es *GRPCEndpointSpec) Addr() string {
// API address should not change between state changes.
return es.addr
}
// Metadata method for gRPC endpoint tries to call InfoAPI exposed by Thanos components until context timeout. If we are unable to get metadata after
// that time, we assume that the host is unhealthy and return error.
func (es *endpointRef) Metadata(ctx context.Context, infoClient infopb.InfoClient, storeClient storepb.StoreClient) (*endpointMetadata, error) {
if infoClient != nil {
resp, err := infoClient.Info(ctx, &infopb.InfoRequest{}, grpc.WaitForReady(true))
if err != nil {
if status.Convert(err).Code() != codes.Unimplemented {
return nil, err
}
} else {
return &endpointMetadata{resp}, nil
}
}
return nil, errors.New(noMetadataEndpointMessage)
}
// stringError forces the error to be a string
// when marshaled into a JSON.
type stringError struct {
originalErr error
}
// MarshalJSON marshals the error into a string form.
func (e *stringError) MarshalJSON() ([]byte, error) {
return json.Marshal(e.originalErr.Error())
}
// Error returns the original underlying error.
func (e *stringError) Error() string {
return e.originalErr.Error()
}
View on GitHub (pinned to 35b8b99117)