Protobuf Wire Decoder
Decode a raw Protocol Buffers message straight from its bytes — no .proto file needed. Paste the message as hex or base64 and the tool walks the wire format, showing each field number, its wire type, and the decoded value, recursing into nested messages just like protoc --decode_raw. It is the fastest way to inspect a captured gRPC payload or a serialized blob when you do not have the schema to hand. Everything is parsed locally; nothing is uploaded.
How to use the Protobuf Wire Decoder
Paste the message bytes and click Decode. With Auto the tool guesses hex or base64 from the characters; force a format with the radio buttons if the guess is wrong (a short all-hex-looking base64 string, for example). You can get the bytes from xxd, a packet capture, a log line, or a base64-encoded field in a JSON document.
The output is an indented tree. Each line shows a field number and its decoded value: plain integers for varints, integers with a float interpretation for fixed 32/64-bit fields, quoted text for length-delimited fields that look like strings, and a nested { … } block for length-delimited fields that parse as sub-messages. Without a schema the decoder cannot show field names or distinguish signed, unsigned, and zig-zag integers — but the structure, numbers, and strings are all recovered.
How the protobuf wire format works
Protocol Buffers serialize a message as a flat sequence of fields, each introduced by a tag. The tag is a varint whose lower three bits are the wire type and whose upper bits are the field number from the .proto definition. The wire type tells a parser how to read the bytes that follow, which is exactly what makes schema-free decoding possible: you cannot recover the field names or the original types, but you can always recover the structure.
There are four wire types in common use. Varint (type 0) is a variable-length integer where each byte contributes seven bits and the high bit signals continuation — it carries int32, int64, bool, and enum values. 64-bit (type 1) and 32-bit (type 5) are fixed-width little-endian values used for fixed64/double and fixed32/float. Length-delimited (type 2) is a varint length followed by that many bytes, and it holds strings, raw bytes, embedded messages, and packed repeated fields all at once.
Because a length-delimited field could be any of those, a schema-free decoder has to guess. This tool tries to parse the bytes as a nested message first; if that fails it checks whether they are printable text and shows a string; otherwise it falls back to a hex dump. That heuristic matches protoc --decode_raw and is right the vast majority of the time, though a short string can occasionally look like a valid tiny message. Ambiguities like signed-versus-unsigned integers or which numeric type a fixed field really was can only be resolved with the original .proto.
Common use cases
- Inspecting gRPC traffic. Decode a captured request or response body when you do not have the proto on hand.
- Debugging serialization. Confirm which fields and values your code actually wrote to the wire.
- Reverse-engineering a blob. Recover the structure of an unknown protobuf payload to reconstruct its schema.
- Learning the format. See exactly how field numbers, wire types, and nested messages are laid out byte by byte.