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

  1. Fix the producer (SDK/exporter) so every exemplar sets IntValue or DoubleValue
  2. Check collector/SDK versions for known exemplar-encoding bugs and upgrade
  3. Drop exemplars with unset values client-side before export
  4. 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

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)