Protobuf Wire Format Decoder
Use this Protobuf Wire Format Decoder to inspect raw Protocol Buffers binary data from hexadecimal bytes. Decode field tags, field numbers, wire types, varints, fixed32, fixed64 and length-delimited values without requiring the original .proto schema.
| # | Offset | Field | Wire Type | Tag Bytes | Value / Length | Payload | Status |
|---|
-
-
What Is a Protobuf Wire Format Decoder?
A Protobuf Wire Format Decoder examines the binary representation produced by Protocol Buffers. Instead of requiring generated source code or a message schema, it reads the low-level tags and payload structures directly from the serialized bytes.
This is useful when debugging network captures, inspecting embedded-device messages, reverse-engineering your own protocol traffic, validating serializer output or understanding why a protobuf message occupies a particular number of bytes.
The decoder cannot reconstruct information that protobuf intentionally omits from the wire stream. Field names and exact declared types normally come from the message definition rather than from the serialized message itself.
How the Protobuf Wire Format Works
A protobuf binary message consists of a sequence of field records. Each record begins with a tag identifying the field number and the wire type.
record =
tag + encoded payload
The wire type tells a parser how to find the end of the field value so unknown fields can be skipped even when the reader does not understand their schema.
Protobuf Tag Formula
The protobuf field tag combines the field number and wire type:
tag =
(field_number << 3)
| wire_type
To decode a tag:
wire_type =
tag & 0x07
field_number =
tag >> 3
The combined tag itself is stored as a protobuf varint.
Protobuf Wire Types
| ID | Wire Type | Payload Format | Common Schema Uses |
|---|---|---|---|
| 0 | Varint | Variable-length integer | int32, int64, uint32, uint64, sint32, sint64, bool, enum |
| 1 | Fixed64 | 8 bytes little-endian | fixed64, sfixed64, double |
| 2 | Length-delimited | Length varint + payload | string, bytes, embedded messages, packed repeated fields |
| 3 | Start Group | Group start marker | Deprecated group encoding |
| 4 | End Group | Group end marker | Deprecated group encoding |
| 5 | Fixed32 | 4 bytes little-endian | fixed32, sfixed32, float |
Example: Decode 08 96 01
One of the standard protobuf encoding examples is:
08 96 01
First decode the tag byte:
0x08 = 8 decimal
Field Number =
8 >> 3
= 1
Wire Type =
8 & 7
= 0
Field 1
Wire Type 0 — Varint
The remaining bytes 96 01 form a varint whose unsigned value is
150.
How Protobuf Varints Work
A protobuf varint stores seven payload bits in each byte. The most significant bit indicates whether another byte follows.
96 01
0x96:
continuation bit = 1
0x01:
continuation bit = 0
decoded value = 150
Small non-negative values therefore use fewer bytes than large values.
Unsigned Varint vs Signed and ZigZag Values
Wire type 0 alone does not tell a schema-free decoder whether the original field was uint32, uint64, int32, int64, sint32, sint64, bool or enum.
For that reason, this tool reports the raw unsigned varint value and a possible ZigZag interpretation. It does not claim that the ZigZag result is the field’s true application value unless the schema says the field is sint32 or sint64.
Length-Delimited Protobuf Fields
Wire type 2 begins with a varint specifying the number of payload bytes that follow.
12 03 61 62 63
12
→ Field 2, wire type 2
03
→ Payload length = 3 bytes
61 62 63
→ Raw payload bytes
Those bytes happen to represent the UTF-8 text abc, but wire type
2 is not automatically a string. It can also represent arbitrary bytes,
embedded protobuf data or a packed repeated scalar field.
Why a Schema Is Needed for Complete Protobuf Decoding
The wire format contains enough information to safely separate fields, but it does not serialize the field names or full schema type declaration.
Wire Format Knows
Field number, wire type, encoded payload boundaries and raw values.
.proto Schema Knows
Field name, exact scalar type, enum definition, nested message type and repeated-field meaning.
This distinction is essential when inspecting protobuf data without its schema.
Fixed32 Protobuf Fields
Wire type 5 consumes exactly four bytes after the tag. The bytes are stored in little-endian order.
Depending on the schema, those same four bytes can represent fixed32, sfixed32 or an IEEE 754 single-precision floating-point value.
The decoder therefore reports the raw 32-bit unsigned value and also provides the corresponding float interpretation as supplemental information.
Fixed64 Protobuf Fields
Wire type 1 consumes exactly eight little-endian payload bytes. Possible schema types include fixed64, sfixed64 and double.
The decoder preserves the exact payload hex, calculates its unsigned 64-bit integer value and also shows the IEEE 754 double interpretation. The schema determines which interpretation is actually intended.
Protobuf Start Group and End Group
Wire types 3 and 4 represent the deprecated protobuf group mechanism. A Start Group tag begins a group associated with a field number, and a corresponding End Group tag closes it.
The decoder tracks group nesting and flags mismatched or unclosed group boundaries instead of silently ignoring them.
Protobuf Field Numbers
A protobuf field number is encoded in the upper portion of the tag after the lowest three wire-type bits are removed.
Field number zero is invalid. Protocol Buffer schemas also reserve field numbers 19000 through 19999 for the implementation, so the decoder marks a wire record in that range as a warning rather than inventing a normal schema field interpretation.
Why Small Field Numbers Use Less Space
Because the field number is part of a varint tag, smaller field numbers normally produce shorter tag encodings. Field numbers 1 through 15 can fit with the wire-type bits into a one-byte tag.
That is one reason frequently occurring protobuf fields are commonly assigned low field numbers.
UTF-8 Preview for Length-Delimited Fields
When a length-delimited payload is valid UTF-8 and contains readable text, the decoder shows a text preview. That preview is deliberately labeled as a preview rather than as proof that the field was declared as a protobuf string.
If the bytes are not valid readable UTF-8, the raw hexadecimal payload remains available without replacing binary data with misleading text.
Embedded Messages and Packed Fields
A length-delimited value may contain another protobuf message. It can also contain packed repeated primitive values. Without the message schema there is no reliable universal way to distinguish those cases merely from wire type 2.
This decoder therefore does not recursively declare every valid-looking byte sequence to be an embedded protobuf message. That avoids false decoding of ordinary byte arrays or strings.
Malformed Protobuf Data Detection
The decoder checks several common wire-format failures, including truncated varints, invalid wire types, field number zero, truncated fixed-width fields, declared length values that exceed the remaining input, and mismatched group markers.
When an unrecoverable structural error occurs, decoding stops at the byte offset where the problem was detected instead of guessing where the following field begins.
Common Uses for a Protobuf Wire Decoder
Network Debugging
Inspect protobuf payload bytes from packet captures or application logs.
Serializer Testing
Confirm that field numbers and low-level encoded values match expectations.
Embedded Systems
Analyze protobuf traffic from constrained devices without running a full protobuf development environment.
Schema Investigation
Identify wire-level field numbers and payload structures before applying a known message definition.
Common Protobuf Wire Format Mistakes
Reading the Tag as a Plain Byte
Tags themselves are varints and can occupy more than one byte.
Assuming Wire Type 2 Means String
Length-delimited values can represent several different protobuf schema types.
Ignoring Little Endian Fixed Values
Fixed32 and Fixed64 payloads are encoded little-endian.
Treating Every Varint as Unsigned Application Data
The schema may define signed, ZigZag, Boolean or enum semantics.
Expecting Field Names on the Wire
Serialized protobuf records contain field numbers, not source-code field names.
Assuming Field Order Is Meaningful
Parsers should not depend on a particular serialization order for fields.
Protobuf Wire Format Decoder FAQs
How do I decode protobuf binary data?
What does protobuf hex 08 96 01 mean?
What is the protobuf tag formula?
What are the protobuf wire types?
What does wire type 0 mean?
What does wire type 1 mean?
What does wire type 2 mean?
What does wire type 5 mean?
Can a protobuf decoder recover field names without the .proto file?
Can this tool tell whether a length-delimited field is a string?
Can wire type 2 contain another protobuf message?
Why are protobuf integers variable length?
What is ZigZag encoding?
Are protobuf fixed32 values little-endian?
Are protobuf fixed64 values little-endian?
Is field number zero valid in protobuf?
Are protobuf field numbers 19000 through 19999 reserved?
Does protobuf preserve field serialization order?
Can this decoder detect malformed protobuf bytes?
Decode Raw Protocol Buffers Wire Data
Paste protobuf hexadecimal bytes to inspect tags, field numbers, wire types, varints, fixed-width values and length-delimited payloads while preserving the important distinction between wire-level facts and schema-dependent meaning.