How to use the protobuf wire format decoder
- Paste the bytes of a protobuf message as hex, with or without spaces, or as Base64.
- Choose Hex or Base64 to match what you pasted.
- Read the table of fields in order, with the path of nested fields written like 3.1.
- Use the Also column to see other readings of the same value, such as signed and zigzag numbers or a double.
Formula
tag = varint; field number = tag >> 3; wire type = tag & 7
wire type 0: varint, 1: 8 bytes, 2: length then that many bytes, 5: 4 bytes
zigzag value = (n >> 1) xor -(n & 1), signed value = n as a 64-bit two's complement number
a varint stores 7 bits per byte, low bits first, and a set top bit means another byte follows
The data contains only numbers and wire types. Without the .proto file, whether a varint is a count, a flag or a zigzag value is unknown, so each reading is offered.
The example from the encoding guide, plus more
The bytes 08 96 01 are a tag 08 (field 1, wire type 0) and the varint 96 01, which is 0x16 + 1 x 128 = 150. The bytes 12 07 followed by testing are field 2, wire type 2, length 7, so the value is the text testing. The bytes 1a 03 08 96 01 are field 3 with length 3, and the 3 bytes inside are themselves field 1 with the value 150.
The default sample combines those three with 25 00 00 80 3f, which is field 4 as a 32-bit value 0x3f800000 that reads as the float 1.0. The tool finds 5 fields in 22 bytes: 4 at the top level and 1 nested message. For 09 18 2d 44 54 fb 21 09 40 the 8 bytes read as the double 3.141592653589793.
Messages, text or bytes
A length-delimited field can hold text, raw bytes, a nested message or a packed list of numbers, and the wire format does not say which. The tool tries a nested message first, as the protoc command does when it decodes raw data. If the content is readable text without control characters, it is also shown as text, and when it is neither it is shown as hex.
To study a single number, the Varint and Zigzag Encoder shows how it is written in bytes. The Hex Viewer lets you look at a whole file, and the Number Base Converter converts a value between hex, decimal and binary.
Errors and what they mean
If the bytes end in the middle of a field, if a length runs past the end, or if a tag has field number 0, the tool names the byte where the problem starts. Groups, the older wire types 3 and 4, and the wire types 6 and 7 are not supported. A message that decodes without any error is not proof that the data is protobuf, since random bytes sometimes parse.
Assumptions and limits
- The bytes are one complete message, with no framing such as a length prefix or a compression header in front.
- Numbers are little endian, as the wire format requires.
- Nested messages are followed up to five levels deep.
- Up to 200,000 characters of input are read, and nothing is uploaded.
Frequently asked questions
Why does a field show as both text and a message?
A short string can happen to be a valid message too. The tool prefers the message when the bytes are not clearly ordinary text, and the Also column shows the other reading when there is one.
Where do the field names come from?
They do not exist in the data. Only numbers are sent, so a decoder without the schema can show field numbers and guess at types, and the schema file supplies the names.
What does zigzag mean?
It is a way to store negative numbers compactly in a varint, by mapping 0, -1, 1, -2 and so on to 0, 1, 2, 3. Fields declared as signed integers of the sint kind use it.
Can I paste a gRPC message?
A gRPC frame begins with a flag byte and a four byte length. Remove those first five bytes and paste what follows, or the first tag will be read from the wrong place.