Protobuf viewer
Decode Protocol Buffers wire format without a .proto file: varint (with zigzag), fixed32/64 and length-delimited fields by field number, with length-delimited payloads recursively probed as nested messages, printable strings or hex bytes.
Runs in your browserEvery computation happens in your browser — your data never leaves this device.
Decoded value
Paste hex bytes to decode them
Selected node
JSON view
Repeated field numbers are aggregated into arrays; byte strings use 0x… and integers outside the safe range stay strings.
What this tool does
- A capture or log gives you raw bytes and no .proto file — paste them here to see field numbers and values before hunting for the schema.
- Debug protobuf payloads in gRPC or Kafka: confirm what a field actually carries and whether field numbers match the interface docs.
- Verify serialization by decoding the hex into a tree and comparing the JSON view, a quick way to spot whether a packed repeated field is packed as expected.
- Reverse-engineer a third-party API by guessing field meanings from field numbers; length-delimited payloads are probed as nested messages first and printable text second.
Example
Input
08 96 01 12 07 74 65 73 74 69 6e 67
Output
{
"1": 150,
"2": "testing"
}Field 1 is a varint (0x96 0x01 = 150) and field 2 is length-delimited, decoded as the printable UTF-8 text "testing".
Frequently asked questions
Can it really decode without a .proto file?
It decodes the wire format, not the schema. Varints, fixed32/64 and length-delimited fields are read per spec, but length-delimited payloads are probed as nested messages first, then printable text, then hex — so type labels are inferences, not authoritative.
What is the zigzag value next to a varint?
sint32 and sint64 use zigzag encoding to map negative numbers onto small positives, and the wire format alone cannot tell them apart, so both interpretations are shown: the raw value for uint32/uint64/int32/int64 and the zigzag value for sint types.
Why does a packed repeated field show up as a byte string?
Packed encoding stuffs a series of numbers into one length-delimited field. Without a schema there is no way to know the element width, so the tool shows the raw bytes — this is expected behaviour.
Why do I get "not valid protobuf data"?
Common causes: truncated input where a declared length exceeds the remaining bytes, an invalid field number or wire type (field number 0, wire type 6/7), a varint longer than ten bytes, or an unclosed group. A missing or extra byte when pasting will do it.
Is the payload uploaded anywhere?
No. Decoding runs entirely in the browser with JavaScript and the page makes no requests, so sensitive binary data never leaves your machine.
Keywords:protobufprotocol bufferswire formatvarintzigzagdecodebinaryProtobuf 解码字段号二进制解析序列化gRPC