openzipkin/zipkin · error · IllegalArgumentException
Expected json, proto3 or thrift list encoding
Error message
Expected json, proto3 or thrift list encoding
What it means
SpanBytesDecoderDetector.decoderForListMessage(ByteBuffer) throws IllegalArgumentException('Expected json, proto3 or thrift list encoding') when the first byte does not identify a list container: not 12 (Thrift List[ThriftSpan]), not 11 (legacy thrift empty-list, zipkin-reporter-java#133), not '[', and not a protobuf3 message. It expects payloads in one of the reporter batch encodings.
Source
Thrown at zipkin/src/main/java/zipkin2/SpanBytesDecoderDetector.java:78
}
return decoder;
}
/**
* Throws {@link IllegalArgumentException} if the input isn't a json, proto3 or thrift list
* message.
*/
public static BytesDecoder<Span> decoderForListMessage(byte[] spans) {
return decoderForListMessage(ByteBuffer.wrap(spans));
}
public static BytesDecoder<Span> decoderForListMessage(ByteBuffer spans) {
BytesDecoder<Span> decoder = detectDecoder(spans);
byte first = spans.get(spans.position());
if (first != 12 /* List[ThriftSpan] */
&& first != 11 /* openzipkin/zipkin-reporter-java#133 */
&& !protobuf3(spans) && first != '[') {
throw new IllegalArgumentException("Expected json, proto3 or thrift list encoding");
}
return decoder;
}
/** @throws IllegalArgumentException if the input isn't a json or thrift list or object. */
static BytesDecoder<Span> detectDecoder(ByteBuffer bytes) {
byte first = bytes.get(bytes.position());
if (first <= 16) { // binary format
if (protobuf3(bytes)) return SpanBytesDecoder.PROTO3;
return SpanBytesDecoder.THRIFT; /* the first byte is the TType, in a range 0-16 */
} else if (first != '[' && first != '{') {
throw new IllegalArgumentException("Could not detect the span format");
}
if (contains(bytes, ENDPOINT_FIELD_SUFFIX)) return SpanBytesDecoder.JSON_V2;
if (contains(bytes, TAGS_FIELD)) return SpanBytesDecoder.JSON_V2;
return SpanBytesDecoder.JSON_V1;
}
View on GitHub (pinned to 878ce2a1fa)
Solutions
- Ensure the payload is decompressed before detection (gunzip when Content-Encoding is gzip).
- Produce the payload with a reporter's list encoder (JSON_V2.encodeList / PROTO3 / Thrift) rather than concatenating raw objects.
- For mixed-shape endpoints, branch on the first byte: '{' -> decoderForMessage path, '[' / 12 / 11 -> list path.
Example fix
// before
BytesDecoder<Span> d = SpanBytesDecoderDetector.decoderForListMessage(raw);
// after
byte[] raw = maybeGunzip(body); // handle Content-Encoding first
BytesDecoder<Span> d = raw[0] == '{'
? SpanBytesDecoderDetector.decoderForMessage(raw)
: SpanBytesDecoderDetector.decoderForListMessage(raw); Defensive patterns
Strategy: try-catch
Validate before calling
byte first = spans.get(spans.position());
if (first != '[' && first != '{' && first > 16 && first != 11 && first != 12) {
// reject early: unsupported or undecoded (compressed?) payload
} Try / catch
try {
decoder = SpanBytesDecoderDetector.decoderForListMessage(buf);
} catch (IllegalArgumentException e) {
// fall back to single-message decoding for '{' payloads, otherwise drop + metric
decoder = SpanBytesDecoderDetector.decoderForMessage(bytes);
} Prevention
- Decompress (gzip) before format detection.
- Branch on the first byte to support mixed single/list ingestion endpoints.
When it happens
Trigger: Passing a single JSON object ('{' first byte), a raw PROTO3 Span struct that fails the protobuf3 heuristic, or arbitrary/corrupt bytes to decoderForListMessage.
Common situations: Collector endpoints receiving mixed payloads (some clients send single objects); truncated or double-compressed payloads (gzip not yet decompressed) whose first byte is garbage; encoding mismatches after upgrading a reporter.
Related errors
- Expected json or thrift object, not list encoding
- v2 formats should only be used with list messages
- Could not detect the span format
- should be a 1 to 32 character lower-hex string with no pref
- input is not a list
AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14).
Data as JSON: /api/errors/3ab70a53be8c0fc0.
Report an issue: GitHub.