thanos-io/thanos · error
parse raw query
Error message
parse raw query %s
What it means
QueryInstant parses the base URL's existing RawQuery with url.ParseQuery before adding the query/time parameters. If that raw query string is malformed (bad percent-encoding, invalid separator), it returns this error wrapping the parse failure and including the raw query string.
Solutions
- Inspect the raw query printed in the error to find the malformed segment
- Use url.Values.Encode() or url.Parse on the full base URL instead of hand-built query strings
- Strip or fix the base URL's RawQuery if pre-existing params are not needed
- Percent-encode any dynamically inserted query values
Example fix
// before
u, _ := url.Parse("http://thanos:9090/api/v1/query?query=%zz") // invalid escape
// after
u, _ := url.Parse("http://thanos:9090/api/v1/query") // let the client add params Defensive patterns
Strategy: validation
Validate before calling
if base.RawQuery != "" {
if _, err := url.ParseQuery(base.RawQuery); err != nil {
return fmt.Errorf("base url has malformed query: %w", err)
}
} Type guard
func hasValidRawQuery(u *url.URL) bool {
_, err := url.ParseQuery(u.RawQuery)
return err == nil
} Try / catch
vec, _, _, err := client.QueryInstant(ctx, base, query, t, opts)
if err != nil && strings.Contains(err.Error(), "parse raw query") {
base.RawQuery = "" // drop malformed params and retry
vec, _, _, err = client.QueryInstant(ctx, base, query, t, opts)
} Prevention
- Build base URLs via url.Parse and url.Values, never string concat
- Strip pre-existing RawQuery when you intend to supply params yourself
- Percent-encode any interpolated values
When it happens
Trigger: The *url.URL passed to QueryInstant contains a RawQuery that url.ParseQuery rejects — e.g. '%' not followed by hex digits, or invalid separators left over from manual URL construction.
Common situations: Building base URLs by string concatenation with hand-written query strings; copying URLs from logs/browsers with encoded characters mishandled; templates injecting unencoded values into the query part.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- parse federation labels
- setup downstream roundtripper
- creating request to downstream URL
- parse alert query url
- no query API server reachable
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/dcc2029f45feba57.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/promclient/promclient.go:430
return errors.Errorf("unknown partial response strategy %v", p.PartialResponseStrategy)
}
// TODO(bwplotka): Apply change from bool to strategy in Query API as well.
values.Add("partial_response", partialResponseValue)
return nil
}
type Explanation struct {
Name string `json:"name"`
Children []*Explanation `json:"children,omitempty"`
}
// QueryInstant performs an instant query using a default HTTP client and returns results in model.Vector type.
func (c *Client) QueryInstant(ctx context.Context, base *url.URL, query string, t time.Time, opts QueryOptions) (model.Vector, []string, *Explanation, error) {
params, err := url.ParseQuery(base.RawQuery)
if err != nil {
return nil, nil, nil, errors.Wrapf(err, "parse raw query %s", base.RawQuery)
}
params.Add("query", query)
params.Add("time", t.Format(time.RFC3339Nano))
if !opts.DoNotAddThanosParams {
if err := opts.AddTo(params); err != nil {
return nil, nil, nil, errors.Wrap(err, "add thanos opts query params")
}
}
u := *base
u.Path = path.Join(u.Path, "/api/v1/query")
u.RawQuery = params.Encode()
level.Debug(c.logger).Log("msg", "querying instant", "url", u.String())
span, ctx := tracing.StartSpan(ctx, "/prom_query_instant HTTP[client]")
defer span.Finish()
View on GitHub (pinned to 35b8b99117)