thanos-io/thanos · error · ApiError
error parsing request form=
Error message
error parsing request form='%v'
What it means
Returned when r.ParseForm() fails while handling the /api/v1/rules request. ParseForm parses the URL query and (for POST) the body; a malformed query string or unreadable body triggers this. Note a copy-paste quirk: the error text interpolates the MatcherParam constant rather than the actual parse error, and it is surfaced as ErrorInternal (HTTP 500).
Solutions
- URL-encode query parameters properly (e.g. use url.Values.Encode / encodeURIComponent for match[] regexes).
- Remove or fix malformed percent-escapes in the request URL.
- Inspect the wrapped ParseForm error from the HTTP layer for the precise parse failure.
- If the confusing message (which prints the param name, not the cause) is a problem, patch v1.go to wrap the actual err.
Example fix
// before
fetch('/api/v1/rules?match[]=' + expr)
// after
fetch('/api/v1/rules?match[]=' + encodeURIComponent(expr)) Defensive patterns
Strategy: validation
Validate before calling
const qs = new URLSearchParams(); qs.set('match[]', expr); const url = `/api/v1/rules?${qs.toString()}`; // ensures valid percent-encoding Try / catch
try { const r = await fetch(url); if (!r.ok) throw new Error(await r.text()); } catch (e) { console.error('rules request failed:', e.message); } Prevention
- Always build query strings with a URL-encoding helper, never string concatenation.
- Validate match[] regexes before encoding them.
- Avoid POSTing odd bodies to GET-style API endpoints.
When it happens
Trigger: Any /api/v1/rules request whose URL query string or form body cannot be parsed by net/http — e.g. malformed percent-encoding like '%zz' in the query.
Common situations: Hand-crafted URLs with invalid percent-escapes, proxies mangling the query string, or clients sending a corrupt/malformed POST body to the rules endpoint.
Understand the failure class
Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.
Related errors
- failed to get prometheus version
- error marshaling response
- Admin operations are disabled
- ID cannot be empty
- Action cannot be empty
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/c001fb830f897577.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/api/query/v1.go:1481
defer span.Finish()
var (
groups *rulespb.RuleGroups
warnings annotations.Annotations
err error
)
typeParam := r.URL.Query().Get("type")
typ, ok := rulespb.RulesRequest_Type_value[strings.ToUpper(typeParam)]
if !ok {
if typeParam != "" {
return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Errorf("invalid rules parameter type='%v'", typeParam)}, func() {}
}
typ = int32(rulespb.RulesRequest_ALL)
}
if err := r.ParseForm(); err != nil {
return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Errorf("error parsing request form='%v'", MatcherParam)}, func() {}
}
// TODO(bwplotka): Allow exactly the same functionality as query API: passing replica, dedup and partial response as HTTP params as well.
req := &rulespb.RulesRequest{
Type: rulespb.RulesRequest_Type(typ),
PartialResponseStrategy: ps,
MatcherString: r.Form[MatcherParam],
RuleName: r.Form[RuleNameParam],
RuleGroup: r.Form[RuleGroupParam],
File: r.Form[FileParam],
}
tracing.DoInSpan(ctx, "retrieve_rules", func(ctx context.Context) {
groups, warnings, err = client.Rules(ctx, req)
})
if err != nil {
return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Errorf("error retrieving rules: %v", err)}, func() {}
}
return groups, warnings.AsErrors(), nil, func() {}View on GitHub (pinned to 35b8b99117)