jaegertracing/jaeger · error

unsupported span kind: '%s'

Error message

unsupported span kind: '%s'

What it means

mapSpanKindsToOpenTelemetry converts user-supplied span kind strings (e.g. from a query parameter) to OpenTelemetry span kind names using jptrace.StringToProtoSpanKind. If the conversion returns an empty string, the input was not a recognized span kind and the function fails with "unsupported span kind: '%s'". parseSpanKinds propagates it (wrapped by newParseError) when the spanKinds parameter is present in a metrics or search query.

Source

Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/query_parser.go:218

func parseSpanKinds(r *http.Request, paramName string, defaultSpanKinds []string) ([]string, error) {
	query := r.URL.Query()
	jaegerSpanKinds, ok := query[paramName]
	if !ok {
		return defaultSpanKinds, nil
	}
	otelSpanKinds, err := mapSpanKindsToOpenTelemetry(jaegerSpanKinds)
	if err != nil {
		return defaultSpanKinds, newParseError(err, paramName)
	}
	return otelSpanKinds, nil
}

func mapSpanKindsToOpenTelemetry(spanKinds []string) ([]string, error) {
	otelSpanKinds := make([]string, len(spanKinds))
	for i, spanKind := range spanKinds {
		v := jptrace.StringToProtoSpanKind(spanKind)
		if v == "" {
			return otelSpanKinds, fmt.Errorf("unsupported span kind: '%s'", spanKind)
		}
		otelSpanKinds[i] = v
	}
	return otelSpanKinds, nil
}

func newParseError(err error, paramName string) error {
	return fmt.Errorf("unable to parse param '%s': %w", paramName, err)
}

View on GitHub (pinned to 806f444784)

Solutions

  1. Use the exact accepted OTel span kind strings: unspecified, internal, server, client, producer, consumer.
  2. Trim and normalize the spanKinds values before sending (no extra spaces, correct casing per the API's accepted set).
  3. Check the wrapped error from parseSpanKinds — it names the offending parameter and the raw value via this message.
  4. Consult the Jaeger query API docs for the spanKind parameter's accepted vocabulary.

Example fix

// before
GET /api/metrics/latencies?spanKind=SERVER&...
GET /api/traces?spanKind=3&...

// after
GET /api/metrics/latencies?spanKind=server&...
GET /api/traces?spanKind=consumer&...
Defensive patterns

Strategy: validation

Validate before calling

var validKinds = map[string]bool{
    "unspecified": true, "internal": true, "server": true,
    "client": true, "producer": true, "consumer": true,
}
for _, k := range strings.Split(spanKindsParam, ",") {
    if !validKinds[strings.TrimSpace(k)] {
        return fmt.Errorf("invalid span kind: %q", k)
    }
}

Type guard

func isValidSpanKind(s string) bool {
    switch s {
    case "unspecified", "internal", "server", "client", "producer", "consumer":
        return true
    }
    return false
}

Try / catch

otelKinds, err := parseSpanKinds(params.SpanKinds)
if err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest) // message names the bad value
    return
}

Prevention

When it happens

Trigger: parseSpanKinds -> mapSpanKindsToOpenTelemetry is given a spanKinds list containing any string for which jptrace.StringToProtoSpanKind returns "": misspelled values ("server" vs "unspecified" casing variants are matched by the helper, so e.g. "SERVER ", "served", "client-side" fail), empty strings in the list, or arbitrary values passed via the query API.

Common situations: API users pass span kinds with typos or extra whitespace ("inernal"), use Jaeger-legacy kind names or numeric kinds ("2") not accepted by the OTel string mapping, or send an empty value like ?spanKind=.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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