thanos-io/thanos · error

got non-200 response code

Error message

got non-200 response code: %v, response: %v

What it means

Client.ConfiguredFlags treats any HTTP status other than 200 as an error and returns the status code plus the raw response body. The library cannot interpret flags from an error response, so it surfaces both to help diagnose the server-side cause.

Solutions

  1. Read the status code and body in the error message to identify the server-side cause
  2. Fix the base URL so that <base>/api/v1/status/flags resolves correctly
  3. Check for required auth (401/403) and add credentials or allowlist the client
  4. Verify the Prometheus instance is up and healthy via /-/healthy

Example fix

// before
u, _ := url.Parse("http://prometheus:9090/prometheus") // wrong path prefix
// after
u, _ := url.Parse("http://prometheus:9090") // library appends /api/v1/status/flags
Defensive patterns

Strategy: try-catch

Validate before calling

resp, err := http.Get(baseURL + "/api/v1/status/flags")
if err != nil { return err }
if resp.StatusCode != 200 { return fmt.Errorf("status flags endpoint returned %d", resp.StatusCode) }

Type guard

func isNon200(err error) bool {
    return err != nil && strings.Contains(err.Error(), "non-200 response code")
}

Try / catch

flags, err := client.ConfiguredFlags(ctx)
if err != nil {
    if isNon200(err) { /* check upstream health/auth from code+body in msg */ }
    return err
}

Prevention

When it happens

Trigger: Prometheus (or an intermediary) answered /api/v1/status/flags with 4xx/5xx: wrong endpoint path, auth required (401/403), service down (502/503), or method not allowed.

Common situations: Misconfigured --prometheus.url pointing to the UI root instead of the API base; reverse proxy requiring authentication; Prometheus restarted or temporarily unavailable; hitting a Thanos Query endpoint that lacks the flags status API.

Related errors


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

Appendix: source

Thrown at pkg/promclient/promclient.go:329

	if err != nil {
		return Flags{}, errors.New("failed to read body")
	}

	switch resp.StatusCode {
	case 404:
		return Flags{}, ErrFlagEndpointNotFound
	case 200:
		var d struct {
			Data Flags `json:"data"`
		}

		if err := json.Unmarshal(b, &d); err != nil {
			return Flags{}, errors.Wrapf(err, "unmarshal response: %v", string(b))
		}

		return d.Data, nil
	default:
		return Flags{}, errors.Errorf("got non-200 response code: %v, response: %v", resp.StatusCode, string(b))
	}

}

// Snapshot will request Prometheus to perform snapshot in directory returned by this function.
// Returned directory is relative to Prometheus data-dir.
// NOTE: `--web.enable-admin-api` flag has to be set on Prometheus.
// Added to Prometheus from v2.1.
// TODO(bwplotka): Add metrics.
func (c *Client) Snapshot(ctx context.Context, base *url.URL, skipHead bool) (string, error) {
	u := *base
	u.Path = path.Join(u.Path, "/api/v1/admin/tsdb/snapshot")

	req, err := http.NewRequest(
		http.MethodPost,
		u.String(),
		strings.NewReader(url.Values{"skip_head": []string{strconv.FormatBool(skipHead)}}.Encode()),
	)

View on GitHub (pinned to 35b8b99117)