thanos-io/thanos · error
unmarshal alertmanager alert API response
Error message
unmarshal alertmanager alert API response
What it means
AlertmanagerAlerts fetches /api/v1/alerts from an Alertmanager and decodes the 2xx body into a struct with a data field of []*model.Alert. This error wraps json.Unmarshal failing because the body is not valid JSON or does not match that envelope (e.g. HTML page, wrong root type, data not an array).
Solutions
- Verify the base URL is the Alertmanager (default :9093), not Prometheus (:9090); log the raw body to confirm.
- Check for auth redirects/SSO proxies that return HTML login pages with status 200.
- Test directly with curl '<base>/api/v1/alerts' and confirm the JSON has a data array.
- Alertmanager API version: ensure the endpoint exists and is not an api/v2-only setup where shapes differ (this client targets the legacy api/v1).
Example fix
// before: wrong server url: http://prometheus:9090 // after: Alertmanager serves /api/v1/alerts url: http://alertmanager:9093
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: confirm this is Alertmanager's API resp, _ := http.Get(base + "/api/v1/status/buildinfo") // AM returns 200 with version info; Prom buildinfo schema differs // or simply check the configured port (9093 vs 9090) before constructing the client
Try / catch
alerts, err := client.AlertmanagerAlerts(ctx, u)
if err != nil && strings.Contains(err.Error(), "unmarshal alertmanager alert API response") {
// wrong endpoint or HTML-200 portal page: log body/URL
return err
} Prevention
- Use the Alertmanager address/port (default 9093), not Prometheus
- Beware SSO/auth proxies returning HTML 200 pages
- Verify /api/v1/alerts is available (legacy API enabled) on your Alertmanager version
When it happens
Trigger: Client.AlertmanagerAlerts receives a 2xx response whose body fails to decode into {"data": [alert...]} — non-JSON body, data as object/string, or unexpected field types inside alerts.
Common situations: Pointing the client at the Prometheus API instead of Alertmanager (different response shape), an authentication portal returning an HTML 200 page, wrong port or path prefix, or a proxy intercepting the request.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- unmarshal response
- unmarshal query range response
- unmarshal marker JSON
- unmarshal query instant response
- decode result into ValueTypeMatrix
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/ff48f5e05ea3013f.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/promclient/promclient.go:653
u.Path = path.Join(u.Path, "/api/v1/alerts")
level.Debug(c.logger).Log("msg", "querying instant", "url", u.String())
span, ctx := tracing.StartSpan(ctx, "/alertmanager_alerts HTTP[client]")
defer span.Finish()
body, _, err := c.req2xx(ctx, &u, http.MethodGet, nil)
if err != nil {
return nil, err
}
// Decode only ResultType and load Result only as RawJson since we don't know
// structure of the Result yet.
var v struct {
Data []*model.Alert `json:"data"`
}
if err = json.Unmarshal(body, &v); err != nil {
return nil, errors.Wrap(err, "unmarshal alertmanager alert API response")
}
sort.Slice(v.Data, func(i, j int) bool {
return v.Data[i].Labels.Before(v.Data[j].Labels)
})
return v.Data, nil
}
// BuildVersion returns Prometheus version from /api/v1/status/buildinfo Prometheus endpoint.
// For Prometheus versions < 2.14.0 it returns "0" as Prometheus version.
func (c *Client) BuildVersion(ctx context.Context, base *url.URL) (string, error) {
u := *base
u.Path = path.Join(u.Path, "/api/v1/status/buildinfo")
level.Debug(c.logger).Log("msg", "build version", "url", u.String())
span, ctx := tracing.StartSpan(ctx, "/prom_buildversion HTTP[client]")
defer span.Finish()
View on GitHub (pinned to 35b8b99117)