thanos-io/thanos · error
unsupported exemplar value type
Error message
unsupported exemplar value type: %v
What it means
getPromExemplars converts OTLP exemplars to Prometheus exemplars. Exemplar values must be int or double; any other value type hits the default branch and returns this error, dropping exemplar conversion.
Solutions
- Fix the producer (SDK/exporter) so every exemplar sets IntValue or DoubleValue
- Check collector/SDK versions for known exemplar-encoding bugs and upgrade
- Drop exemplars with unset values client-side before export
- Validate with the newest proto definitions that the value oneof is populated
Example fix
// before: exemplar created without a value ex := pmetric.NewExemplar() ex.SetTimestamp(...) // after ex := pmetric.NewExemplar() ex.SetDoubleValue(latencySeconds)
Defensive patterns
Strategy: type-guard
Validate before calling
for i := 0; i < exs.Len(); i++ {
ex := exs.At(i)
if ex.ValueType() != pmetric.ExemplarValueTypeInt && ex.ValueType() != pmetric.ExemplarValueTypeDouble {
return errors.New("exemplar without a value")
}
} Type guard
func hasValue(ex pmetric.Exemplar) bool {
return ex.ValueType() == pmetric.ExemplarValueTypeInt || ex.ValueType() == pmetric.ExemplarValueTypeDouble
} Try / catch
exemplars, err := getPromExemplars(md.Exemplars(), ...)
if err != nil {
if strings.Contains(err.Error(), "unsupported exemplar value type") {
log.Warnf("dropping exemplars: %v", err)
return nil
}
return err
} Prevention
- Verify exporter SDKs always set exemplar Int/Double value
- Keep collector and SDK versions aligned on proto/oneof handling
- Round-trip test exemplars through your pipeline
When it happens
Trigger: An OTLP exemplar whose ValueType() is neither ExemplarValueTypeInt nor ExemplarValueTypeDouble — i.e. an unset/empty exemplar value, typically from a producer that created exemplars without setting a value or from a codec/protobuf mismatch.
Common situations: Custom OTLP exporters building exemplars manually and leaving the oneof value unset; corrupted or truncated protobuf from a broken collector pipeline; SDK version producing exemplar structs with zeroed value fields.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/944b3a09a9dfff7c.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/receive/otlptranslator/helper.go:370
promExemplars := make([]prompb.Exemplar, 0, pt.Exemplars().Len())
for i := 0; i < pt.Exemplars().Len(); i++ {
if err := everyN.checkContext(ctx); err != nil {
return nil, err
}
exemplar := pt.Exemplars().At(i)
exemplarRunes := 0
promExemplar := prompb.Exemplar{
Timestamp: timestamp.FromTime(exemplar.Timestamp().AsTime()),
}
switch exemplar.ValueType() {
case pmetric.ExemplarValueTypeInt:
promExemplar.Value = float64(exemplar.IntValue())
case pmetric.ExemplarValueTypeDouble:
promExemplar.Value = exemplar.DoubleValue()
default:
return nil, fmt.Errorf("unsupported exemplar value type: %v", exemplar.ValueType())
}
if traceID := exemplar.TraceID(); !traceID.IsEmpty() {
val := hex.EncodeToString(traceID[:])
exemplarRunes += utf8.RuneCountInString(traceIDKey) + utf8.RuneCountInString(val)
promLabel := labelpb.ZLabel{
Name: traceIDKey,
Value: val,
}
promExemplar.Labels = append(promExemplar.Labels, promLabel)
}
if spanID := exemplar.SpanID(); !spanID.IsEmpty() {
val := hex.EncodeToString(spanID[:])
exemplarRunes += utf8.RuneCountInString(spanIDKey) + utf8.RuneCountInString(val)
promLabel := labelpb.ZLabel{
Name: spanIDKey,
Value: val,
}View on GitHub (pinned to 35b8b99117)