jaegertracing/jaeger · error
unexpected metrics ValueType: %s
Error message
unexpected metrics ValueType: %s
What it means
The Prometheus Translator.ToDomainMetricsFamily expects Prometheus query results as a model.Matrix (range vector), since Jaeger metrics are returned as time series. If the model.Value's type is anything other than model.ValMatrix (e.g. ValVector, ValScalar, ValString), translation is impossible and this error reports the unexpected value type.
Source
Thrown at internal/storage/metricstore/prometheus/metricstore/dbmodel/to_domain.go:31
)
// Translator translates Prometheus's metrics model to Jaeger's.
type Translator struct {
labelMap map[string]string
}
// New returns a new Translator.
func New(spanNameLabel string) Translator {
return Translator{
// "operation" is the label name that Jaeger UI expects.
labelMap: map[string]string{spanNameLabel: "operation"},
}
}
// ToDomainMetricsFamily converts Prometheus' representation of metrics query results to Jaeger's.
func (d Translator) ToDomainMetricsFamily(name, description string, mv model.Value) (*metrics.MetricFamily, error) {
if mv.Type() != model.ValMatrix {
return &metrics.MetricFamily{}, fmt.Errorf("unexpected metrics ValueType: %s", mv.Type())
}
return &metrics.MetricFamily{
Name: name,
Type: metrics.MetricType_GAUGE,
Help: description,
Metrics: d.toDomainMetrics(mv.(model.Matrix)),
}, nil
}
// toDomainMetrics converts Prometheus' representation of metrics to Jaeger's.
func (d Translator) toDomainMetrics(matrix model.Matrix) []*metrics.Metric {
ms := make([]*metrics.Metric, matrix.Len())
for i, ss := range matrix {
ms[i] = &metrics.Metric{
Labels: d.toDomainLabels(ss.Metric),
MetricPoints: toDomainMetricPoints(ss.Values),
}
}View on GitHub (pinned to 806f444784)
Solutions
- Use a range query (query_range) so Prometheus returns a model.Matrix.
- Verify the PromQL expression selects an existing metric series over a range (e.g. rate(...[5m])).
- Check the caller that fetched mv: it must pass mv from a Matrix-typed response, not a Vector.
- Add a caller-side check `if mv.Type() != model.ValMatrix { ... }` before invoking the translator.
Example fix
// before
fam, err := translator.ToDomainMetricsFamily(name, desc, result.Vector)
// after
if result.Value.Type() != model.ValMatrix {
return nil, fmt.Errorf("expected matrix, got %s", result.Value.Type())
}
fam, err := translator.ToDomainMetricsFamily(name, desc, result.Value) Defensive patterns
Strategy: type-guard
Validate before calling
if mv.Type() != model.ValMatrix {
return fmt.Errorf("expected range-vector (matrix) result, got %s; use query_range", mv.Type())
} Type guard
func isMatrix(v model.Value) (model.Matrix, bool) {
m, ok := v.(model.Matrix)
return m, ok && v.Type() == model.ValMatrix
} Try / catch
fam, err := translator.ToDomainMetricsFamily(name, desc, mv)
if err != nil {
log.Printf("prometheus result unusable: %v", err) // names the actual type
return nil, err
} Prevention
- Always query Prometheus range endpoints (/query_range) for Jaeger metrics.
- Assert the PromQL expression returns series, not scalars or instant vectors.
- Type-assert with the comma-ok form after checking model.ValMatrix.
When it happens
Trigger: Calling ToDomainMetricsFamily with a result from a Prometheus query that returned an instant vector/scalar instead of a matrix — e.g. using an instant query API response or a query expression yielding a scalar.
Common situations: Feeding results from /api/v1/query (instant) instead of /api/v1/query_range; a metric name typo causing Prometheus to return an empty/scalar-typed value; custom storage plugins passing the wrong model.Value variant.
Related errors
- failed getting error metrics: %w
- failed getting call metrics: %w
- failed executing metrics query: %w
- please provide at least one service name
- unknown metrics backend specified
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/0533c2402c0a8670.
Report an issue: GitHub.