A raw Protobuf decoder reads Protocol Buffers wire-format bytes without a schema. It can't know field names, but it can recover each field's number, its wire type and its value, which is often enough to understand an unknown message.
Example
08 96 01 12 05 68 65 6c 6c 6f 1a 03 08 e8 071: 150
2: "hello"
3 {
1: 1000
}
Top-level fields: 3Field 1 is the varint 150, field 2 is the string "hello", and field 3 is a nested message holding field 1 = 1000. Without a schema the field names are unknown, but the structure is recovered.
How the wire format works
A Protobuf message is a sequence of fields. Each field starts with a tag, a varint holding (field_number << 3) | wire_type:
| Wire type | Meaning | Used for |
|---|---|---|
| 0 | VARINT | int32, int64, uint*, bool, enum, sint* (zigzag) |
| 1 | I64 | fixed64, sfixed64, double |
| 2 | LEN | string, bytes, embedded messages, packed repeated fields |
| 5 | I32 | fixed32, sfixed32, float |
Varints store 7 bits per byte, and the high bit means "more bytes follow". 96 01 is 0x16 + (0x01 << 7) = 150.
Example: the bytes 08 96 01 are one field. The tag 08 means field 1, wire type 0, and the varint 96 01 is the value 150.
Without a schema some things stay ambiguous: a LEN field could be a string, raw bytes or a nested message, and a varint could be signed, unsigned or zigzag-encoded. Raw decoders guess, usually by trying to parse LEN fields as nested messages first.
How to use the Protobuf decoder
- Paste the message bytes as hex or Base64, or open a
.binfile. - Read the fields by number, with nested messages indented.
- A length-delimited field is shown as a nested message when its bytes parse as one, and as a string otherwise.
A gRPC frame (a 1-byte compression flag and a 4-byte length before the message) is detected and stripped automatically. protoc --decode_raw does the same job on the command line.
Protobuf at a glance
| Specification | Protocol Buffers encoding guide (protobuf.dev) |
| Tag | Varint of (field_number << 3) | wire_type |
| Deprecated wire types | 3 and 4 (groups) |
| Schema needed for | Field names and exact types |
Frequently asked questions
Can I get field names without the .proto file?
No. Names aren't stored in the wire format, only field numbers. Some apps embed descriptors, and gRPC servers with reflection enabled can return their schema.
Why does a string field decode as a nested message?
Both use wire type 2 (LEN). If the bytes happen to form a valid message, a raw decoder may show them as one. Check whether the bytes are readable text.
How do I decode Base64 Protobuf from an API?
Base64-decode it first with the Base64 decoder, then pass the bytes to protoc --decode_raw.
Last reviewed · found a mistake? contact@decoder.tools · view as markdown