openzipkin/zipkin · error · IllegalArgumentException

Malformed: invalid wireType

Error message

Malformed: invalid wireType 

What it means

A protobuf tag's low 3 bits encode the wire type; only values 0 (varint), 1 (64-bit), 2 (length-delimited), 5 (32-bit) are legal in Zipkin's reader (groups 3/7 are unused/obsolete). Proto3Fields.Field.wireType throws 'Malformed: invalid wireType N at byte P' when the key decodes to wire type 3, 4, 6, or 7, meaning the stream is corrupt or not protobuf.

Source

Thrown at zipkin/src/main/java/zipkin2/internal/Proto3Fields.java:58

      this(key >>> 3, key & (1 << 3) - 1, key);
    }

    Field(int fieldNumber, int wireType, int key) {
      this.fieldNumber = fieldNumber;
      this.wireType = wireType;
      this.key = key;
    }

    static int fieldNumber(int key, int byteL) {
      int fieldNumber = key >>> 3;
      if (fieldNumber != 0) return fieldNumber;
      throw new IllegalArgumentException("Malformed: fieldNumber was zero at byte " + byteL);
    }

    static int wireType(int key, int byteL) {
      int wireType = key & (1 << 3) - 1;
      if (wireType != 0 && wireType != 1 && wireType != 2 && wireType != 5) {
        throw new IllegalArgumentException(
          "Malformed: invalid wireType " + wireType + " at byte " + byteL);
      }
      return wireType;
    }

    static boolean skipValue(ReadBuffer buffer, int wireType) {
      int remaining = buffer.available();
      switch (wireType) {
        case WIRETYPE_VARINT:
          for (int i = 0; i < remaining; i++) {
            if (buffer.readByte() >= 0) return true;
          }
          return false;
        case WIRETYPE_FIXED64:
          return buffer.skip(8) == 8;
        case WIRETYPE_LENGTH_DELIMITED:
          int length = buffer.readVarint32();
          return buffer.skip(length) == length;

View on GitHub (pinned to 878ce2a1fa)

Solutions

  1. Use the reported byte offset to hex-dump the region and confirm whether the stream is proto3 at all.
  2. Check the preceding field's length prefix for off-by-one bugs in any custom encoding path.
  3. Send the payload through a reference protobuf parser (protoc --decode with zipkin2.proto) to locate the first invalid tag.
  4. Fix the producer to use SpanBytesEncoder.PROTO3 instead of hand-rolled serialization.

Example fix

// before
// custom hand-rolled encoder wrote field key 0x1d (wireType 5) for a string

// after
// use the shipped codec so tags are always well-formed
byte[] bytes = SpanBytesEncoder.PROTO3.encode(span);
Defensive patterns

Strategy: try-catch

Try / catch

try { decode(bytes); } catch (IllegalArgumentException e) { if (e.getMessage().contains("invalid wireType")) { quarantine(bytes); return List.of(); } throw e; }

Prevention

When it happens

Trigger: PROTO3 span decoding hits a tag whose key & 0x7 yields an illegal value — usually the reader is misaligned (after a bad length or truncated varint) or the bytes are another format entirely.

Common situations: Non-proto bytes fed to the proto3 decoder; a producer writing wrong varint tags; corrupted blobs in storage; concatenating two encodings without proper framing.

Understand the failure class

Related errors


AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14). Data as JSON: /api/errors/5a3db77e15020eba. Report an issue: GitHub.