thanos-io/thanos · error
unmarshaling scalar value from
Error message
unmarshaling scalar value from %v
What it means
The second element of the scalar tuple must decode into model.SampleValue (a float64). This error wraps json.Unmarshal failing on resultPointSlice[1] — the value element is not a number-compatible JSON value (e.g. a non-numeric string, null, or an object).
Solutions
- Ensure the value element is a numeric JSON value or a string that parses as float (Prometheus emits values as strings like "42"; model.SampleValue accepts those).
- Log resultPointSlice[1] to inspect the actual payload.
- Fix the emitting server/fixture to return Prometheus-style numeric strings.
- Replace null placeholders with numeric values (0) if the source cannot produce a real sample.
Example fix
// before "result": [1710000000000, "n/a"] // after "result": [1710000000000, "42"]
Defensive patterns
Strategy: validation
Validate before calling
// fixture check: tuple[1] must parse as float
var val model.SampleValue
if err := json.Unmarshal(raw[1], &val); err != nil {
return fmt.Errorf("scalar value must be numeric, got %s", raw[1])
} Try / catch
if err != nil && strings.Contains(err.Error(), "unmarshaling scalar value") {
// value element wrong type; log raw payload and fix emitter
} Prevention
- Emit values as numbers or numeric strings ("42"), never "n/a"/units/null
- Validate fixtures with promtool or against live server output
- Handle NaN/Inf using Prometheus JSON conventions, not custom strings
When it happens
Trigger: QueryInstant/TestRule_UnmarshalScalarResponse receives a scalar result whose tuple[1] cannot parse as a float: strings like "NaN" outside quotes handling, "n/a", units embedded in values, or null.
Common situations: Nonstandard backends returning formatted values ("1.2k", "12%"), null for missing data, or test fixtures with wrong value types.
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
- unmarshaling scalar time from
- unmarshal response
- unmarshal query instant response
- decode result into ValueTypeScalar
- unmarshal query range response
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/f737ebda67d86b8a.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/promclient/promclient.go:624
func convertScalarJSONToVector(scalarJSONResult json.RawMessage) (model.Vector, error) {
var (
// Do not specify exact length of the expected slice since JSON unmarshaling
// would make the length fit the size and we won't be able to check the length afterwards.
resultPointSlice []json.RawMessage
resultTime model.Time
resultValue model.SampleValue
)
if err := json.Unmarshal(scalarJSONResult, &resultPointSlice); err != nil {
return nil, err
}
if len(resultPointSlice) != 2 {
return nil, errors.Errorf("invalid scalar result format %v, expected timestamp -> value tuple", resultPointSlice)
}
if err := json.Unmarshal(resultPointSlice[0], &resultTime); err != nil {
return nil, errors.Wrapf(err, "unmarshaling scalar time from %v", resultPointSlice)
}
if err := json.Unmarshal(resultPointSlice[1], &resultValue); err != nil {
return nil, errors.Wrapf(err, "unmarshaling scalar value from %v", resultPointSlice)
}
return model.Vector{&model.Sample{
Metric: model.Metric{},
Value: resultValue,
Timestamp: resultTime}}, nil
}
// AlertmanagerAlerts returns alerts from Alertmanager.
func (c *Client) AlertmanagerAlerts(ctx context.Context, base *url.URL) ([]*model.Alert, error) {
u := *base
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)View on GitHub (pinned to 35b8b99117)