jaegertracing/jaeger · error

failed to marshal map attribute

Error message

failed to marshal map attribute %q: %w

What it means

buildMapAttributeCondition serializes a map-typed attribute via marshalValueForQuery before building the @map@ condition. A marshal failure is wrapped with this message, naming the attribute key, and aborts query construction.

Solutions

  1. Check the wrapped error to identify which map value failed to serialize
  2. Flatten nested map values into string/int entries before querying
  3. Pre-marshal map attributes in the caller to catch issues early
  4. Restrict query attributes to maps of scalar values

Example fix

// before: nested map value
m.PutVal("nested", pcommon.NewValueEmpty().SetEmptyMapVal())
// after: scalar values only
m.PutStr("nested", flattenedJSON)
Defensive patterns

Strategy: validation

Validate before calling

for _, k := range attr.Map().Keys() {
    v := attr.MapVal()
    val, _ := v.Get(k)
    t := val.Type()
    if t == pcommon.ValueTypeMap || t == pcommon.ValueTypeSlice {
        return fmt.Errorf("map attribute %q has non-scalar value %q", key, k)
    }
}

Type guard

func isScalarOnlyMap(v pcommon.Value) bool {
    if v.Type() != pcommon.ValueTypeMap { return false }
    ok := true
    v.Map().Range(func(_ string, val pcommon.Value) bool {
        if val.Type() == pcommon.ValueTypeMap || val.Type() == pcommon.ValueTypeSlice {
            ok = false
        }
        return ok
    })
    return ok
}

Try / catch

traceIDs, err := store.FindTraceIDs(ctx, query)
if err != nil && strings.Contains(err.Error(), "failed to marshal map attribute") {
    log.Warn("unserializable map attribute in query", "err", err)
    return err
}

Prevention

When it happens

Trigger: A FindTraceIDs query includes a map attribute whose values cannot be marshaled — e.g. a map containing nested unsupported value types or a corrupt pcommon.Value map.

Common situations: Passing OTLP-derived map attributes (e.g. http.request.headers) with nested containers into the search API; programmatic construction of malformed map values.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/d9d81fc1d6275f7f. Report an issue: GitHub.

Appendix: source

Thrown at internal/storage/v2/clickhouse/tracestore/query_builder.go:253

	return append(args, key, value, key, value, key, value, key, value, key, value)
}

func buildBytesAttributeCondition(q *strings.Builder, args []any, key string, attr pcommon.Value) []any {
	return buildSimpleAttributeCondition(q, args, "@bytes@"+key, pcommon.ValueTypeBytes, base64.StdEncoding.EncodeToString(attr.Bytes().AsRaw()))
}

func buildSliceAttributeCondition(q *strings.Builder, args []any, key string, attr pcommon.Value) ([]any, error) {
	b, err := marshalValueForQuery(attr)
	if err != nil {
		return args, fmt.Errorf("failed to marshal slice attribute %q: %w", key, err)
	}
	return buildSimpleAttributeCondition(q, args, "@slice@"+key, pcommon.ValueTypeSlice, b), nil
}

func buildMapAttributeCondition(q *strings.Builder, args []any, key string, attr pcommon.Value) ([]any, error) {
	b, err := marshalValueForQuery(attr)
	if err != nil {
		return args, fmt.Errorf("failed to marshal map attribute %q: %w", key, err)
	}
	return buildSimpleAttributeCondition(q, args, "@map@"+key, pcommon.ValueTypeMap, b), nil
}

func parseStringToTypedValue(key string, attr pcommon.Value, t pcommon.ValueType) (typedAttributeValue, error) {
	switch t {
	case pcommon.ValueTypeBool:
		b, parseErr := strconv.ParseBool(attr.Str())
		if parseErr != nil {
			return typedAttributeValue{}, fmt.Errorf("failed to parse bool attribute %q: %w", key, parseErr)
		}
		return typedAttributeValue{key: key, value: b, valueType: t}, nil
	case pcommon.ValueTypeDouble:
		f, parseErr := strconv.ParseFloat(attr.Str(), 64)
		if parseErr != nil {
			return typedAttributeValue{}, fmt.Errorf("failed to parse double attribute %q: %w", key, parseErr)
		}
		return typedAttributeValue{key: key, value: f, valueType: t}, nil

View on GitHub (pinned to 806f444784)