thanos-io/thanos · error · ApiError

invalid targets parameter state=

Error message

invalid targets parameter state='%v'

What it means

This error is returned by the Thanos Query API's /targets endpoint when the 'state' query parameter contains a value that does not map to any known TargetsRequest_State enum value (ANY, ACTIVE, DROPPED, UNHEALTHY). The handler looks up strings.ToUpper(stateParam) in the generated protobuf enum map, and only throws when a non-empty value was supplied that isn't in the map. It is a client-side input validation error (ErrorBadData, HTTP 400).

Solutions

  1. Use one of the allowed values, case-insensitively: any, active, dropped, unhealthy.
  2. Omit the 'state' parameter entirely to default to ANY.
  3. Check the TargetsRequest_State enum in pkg/targets/targetspb (targets.proto) for the authoritative list of values.

Example fix

// before
curl 'http://query:9090/api/v1/targets?state=down'
// after
curl 'http://query:9090/api/v1/targets?state=unhealthy'
Defensive patterns

Strategy: validation

Validate before calling

const allowed = ['any','active','dropped','unhealthy'];
const state = params.get('state');
if (state && !allowed.includes(state.toLowerCase())) throw new Error(`invalid state='${state}'; use one of ${allowed.join(',')}`);

Prevention

When it happens

Trigger: GET /api/v1/targets?state=foo with any value other than (case-insensitively) ANY, ACTIVE, DROPPED, or UNHEALTHY.

Common situations: Typo like 'state=acitve', passing 'all' instead of 'any', passing free-form text scraped from another Prometheus-like API that uses different state names, or scripting against the endpoint without checking the protobuf enum values.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/9a905e1ef10ec4c1. Report an issue: GitHub.

Appendix: source

Thrown at pkg/api/query/v1.go:1388

		statuses[status.ComponentType.String()] = append(statuses[status.ComponentType.String()], filteredStatus)
	}
	return statuses, nil, nil, func() {}
}

// NewTargetsHandler created handler compatible with HTTP /api/v1/targets https://prometheus.io/docs/prometheus/latest/querying/api/#targets
// which uses gRPC Unary Targets API.
func NewTargetsHandler(client targets.UnaryClient, enablePartialResponse bool) func(*http.Request) (any, []error, *api.ApiError, func()) {
	ps := storepb.PartialResponseStrategy_ABORT
	if enablePartialResponse {
		ps = storepb.PartialResponseStrategy_WARN
	}

	return func(r *http.Request) (any, []error, *api.ApiError, func()) {
		stateParam := r.URL.Query().Get("state")
		state, ok := targetspb.TargetsRequest_State_value[strings.ToUpper(stateParam)]
		if !ok {
			if stateParam != "" {
				return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Errorf("invalid targets parameter state='%v'", stateParam)}, func() {}
			}
			state = int32(targetspb.TargetsRequest_ANY)
		}

		req := &targetspb.TargetsRequest{
			State:                   targetspb.TargetsRequest_State(state),
			PartialResponseStrategy: ps,
		}

		t, warnings, err := client.Targets(r.Context(), req)
		if err != nil {
			return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(err, "retrieving targets")}, func() {}
		}

		return t, warnings.AsErrors(), nil, func() {}
	}
}

View on GitHub (pinned to 35b8b99117)