{"record":{"id":"ef3dc117e1ff46ce","repo":"openzipkin/zipkin","slug":"s-reading-s-from-proto3","errorCode":null,"errorMessage":"%s reading %s from proto3","messagePattern":"(.+?) reading (.+?) from proto3","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"zipkin/src/main/java/zipkin2/internal/Proto3Codec.java","lineNumber":74,"sourceCode":"    int length = buffer.available();\n    if (length == 0) return false;\n    try {\n      while (buffer.pos() < length) {\n        Span span = SPAN.read(buffer);\n        if (span == null) return false;\n        out.add(span);\n      }\n    } catch (RuntimeException e) {\n      throw exceptionReading(\"List<Span>\", e);\n    }\n    return true;\n  }\n\n  static IllegalArgumentException exceptionReading(String type, Exception e) {\n    String cause = e.getMessage() == null ? \"Error\" : e.getMessage();\n    if (cause.contains(\"Malformed\")) cause = \"Malformed\";\n    String message = format(\"%s reading %s from proto3\", cause, type);\n    throw new IllegalArgumentException(message, e);\n  }\n}\n","sourceCodeStart":56,"sourceCodeEnd":77,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin/src/main/java/zipkin2/internal/Proto3Codec.java#L56-L77","documentation":"Zipkin's proto3 codec wraps lower-level protobuf decode failures into an IllegalArgumentException formatted '<cause> reading <type> from proto3'. The wrapped cause is usually one of the 'Malformed: ...' messages from Proto3Fields/ReadBuffer (invalid wireType, fieldNumber zero, truncated buffer, oversized varint). The original exception stays attached as the cause.","triggerScenarios":"Calling SpanBytesDecoder.PROTO3.decode/decodeList with bytes that are not length-delimited protobuf spans: wrong wire format, corrupted/truncated payload, or bytes produced by an incompatible schema/field numbering. Also hit by zipkin-server's proto3 collector endpoint receiving garbage.","commonSituations":"Sending JSON to a grpc/proto3 endpoint; a hand-rolled encoder emitting wrong varint keys; a Kafka/RabbitMQ topic mixing encodings; partial reads from storage where only a prefix of the protobuf blob was stored.","solutions":["Call getCause() on the exception to find the exact protobuf defect (wireType, fieldNumber, truncation, varint size) and byte offset.","Confirm both sides use the same encoding: encode with SpanBytesEncoder.PROTO3 and decode with SpanBytesDecoder.PROTO3; check the Content-Type of the collector.","Re-encode the payload from a known-good source (e.g. decode as JSON then re-encode to proto3) to rule out producer bugs.","In streaming consumers, isolate and drop the offending message so one bad span cannot stop the collector."],"exampleFix":"// before\nList<Span> spans = SpanBytesDecoder.PROTO3.decodeList(bytes);\n\n// after\nList<Span> spans;\ntry {\n  spans = SpanBytesDecoder.PROTO3.decodeList(bytes);\n} catch (IllegalArgumentException e) {\n  LOG.warn(\"dropping malformed proto3 span batch of {} bytes\", bytes.length, e);\n  spans = Collections.emptyList();\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { spans = SpanBytesDecoder.PROTO3.decodeList(bytes); } catch (IllegalArgumentException e) { LOG.warn(\"malformed proto3 batch ({} bytes)\", bytes.length, e); spans = List.of(); }","preventionTips":["Use grpc/HTTP2 collectors only with proto3 Content-Type; keep JSON on the JSON endpoint.","Prefer SpanBytesEncoder.PROTO3 over hand serialization.","Log the cause chain — the wrapped 'Malformed: ...' message names the exact defect."],"tags":["zipkin","protobuf","decoding","span"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}