jaegertracing/jaeger · error

unable to parse param

Error message

unable to parse param '%s': %w

What it means

newParseError is the single wrapping helper all query-parameter parsers (latencies, parseMetricsQueryParams, parseTime, parseDuration, parseBool, parseSpanKinds) use to annotate a parse failure with the parameter name, producing "unable to parse param '%s': %w". It tells the API caller exactly which query parameter was malformed and why. It is a message-structuring error, always caused by a lower-level parse failure.

Solutions

  1. Read the wrapped cause after the parameter name to see the exact parse failure and correct the value.
  2. For times use RFC3339/UTC format; for durations use Go-style units (e.g. 1h30m); for booleans use true/false; for span kinds use the accepted OTel strings.
  3. Validate query parameters client-side before building the request.
  4. URL-encode values so stray characters do not corrupt parsing.

Example fix

// before
GET /api/traces?start=2024-01-01 10:00&end=never

// after
GET /api/traces?start=2024-01-01T10%3A00%3A00Z&end=2024-01-01T11%3A00%3A00Z&lookback=1h
Defensive patterns

Strategy: validation

Validate before calling

func validateParams(p url.Values) error {
    if v := p.Get("start"); v != "" {
        if _, err := time.Parse(time.RFC3339, v); err != nil {
            return fmt.Errorf("start must be RFC3339: %w", err)
        }
    }
    if v := p.Get("lookback"); v != "" {
        if _, err := time.ParseDuration(v); err != nil {
            return fmt.Errorf("lookback must be a Go duration: %w", err)
        }
    }
    return nil
}

Type guard

func isRFC3339(s string) bool {
    _, err := time.Parse(time.RFC3339, s)
    return err == nil
}

Try / catch

mq, err := parseMetricsQueryParams(r.URL.Query())
if err != nil {
    // err is 'unable to parse param <name>: <cause>'
    http.Error(w, err.Error(), http.StatusBadRequest)
    return
}

Prevention

When it happens

Trigger: Any Jaeger query extension HTTP query where a parameter fails its parser: non-numeric latency values, timestamps outside RFC3339 for parseTime, invalid duration strings for parseDuration, non-boolean values for parseBool, or an unsupported span kind from mapSpanKindsToOpenTelemetry (error 211) wrapped with the param name.

Common situations: Hand-written client requests with ?start=2024-13-45 (invalid date), ?lookback=fortnight (invalid duration), ? SpanKind casing issues, or SDK clients whose time format changed between versions.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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

Appendix: source

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

		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)