— Developer Tools

Free Protobuf Wire Decoder

Decode Protocol Buffers bytes with no .proto file. Every field number, wire type and value, in the format protoc --decode_raw prints.

— Samples
Bytes 24Fields 3Valid
Live

What is a Protobuf Wire Decoder?

Protocol Buffers, or protobuf, is Google’s binary format for structured data, used by gRPC and countless internal APIs. Its bytes carry field numbers but no names, so this decoder reads a message without its .proto schema and shows every field it finds.

The decoder follows the wire format in the official protobuf encoding guide and prints its result the way protoc --decode_raw does. Varints are read as full 64-bit values, groups are supported, and each value gets its other possible readings, such as int64, sint64, float or a packed list.

Key Features

No .proto File Needed

Paste bytes and see field numbers, wire types and values straight away. It’s the quickest way to inspect a message from a service whose schema you don’t have.

Nested Messages Unpacked

Length-delimited fields that parse cleanly are shown as nested blocks with dotted paths such as 1.2.1. Flat mode turns that guess off when you need raw bytes.

Every Reading of a Value

Varints show their unsigned, int64 and zigzag sint64 values, and fixed fields their integer and float values. Packed repeated numbers are listed when the bytes split cleanly.

Errors at a Byte Offset

A cut-off message, an impossible wire type or a length that runs past the end is reported with the field number and offset. You see exactly where the bytes stop making sense.

Captured Traffic Stays Local

Decoding happens in this browser tab and nothing is uploaded. gRPC captures, tokens and user records stay on your machine.

Perfect for everyone

  • Backend and gRPC developers
  • Mobile engineers debugging API traffic
  • Security researchers reading undocumented protocols
  • Anyone holding protobuf bytes without the schema

How to Use the Protobuf Wire Decoder

Paste the message bytes, choose how to treat nested fields, and read the decode.

1

Get the Raw Message Bytes

Copy the payload from a packet capture, proxy, log or database as hex or Base64. For gRPC, drop the 5-byte frame header first so only the message itself remains.

2

Paste and Pick Nested or Flat

Nested decodes length-delimited fields as messages when they parse cleanly. Flat shows every such field as a string, which is safer when a field holds raw bytes.

3

Read the Fields

The raw decode lists fields as protoc does, with nested messages in braces. The table adds the dotted field path, the wire type, and other readings of each value.

4

Match Numbers to Names

Compare the field numbers with the .proto file or generated code if you have it. If decoding fails, the error gives the offset where the bytes went wrong.

Worked Examples

Protobuf Bytes, Decoded

Several of these messages come straight from the protobuf encoding guide. Each answer is what the decoder printed in the mode on its chip, failures included, so work out the fields first and then reveal.

REF_001Varint 150

“08 96 01”

REF_002String field

“12 07 74 65 73 74 69 6e 67”

REF_003Nested message

“1a 03 08 96 01”

REF_004Same bytes, Flat

“1a 03 08 96 01”

REF_005Three-field record

“0a 03 41 64 61 10 1f 1a 0f 61 64 61 40 65 78 61 6d 70 6c 65 2e 63 6f 6d”

REF_006Packed repeated field

“22 06 03 8e 02 9e a7 05”

REF_007int32 -1 on the wire

“08 ff ff ff ff ff ff ff ff ff 01”

REF_00832-bit, float 1.0

“0d 00 00 80 3f”

REF_009Length past the end

“12 0a 74 65 73 74”

REF_010Impossible wire type

“0f”

Wire Format

How Protobuf Encodes a Message

A protobuf message is a run of fields, each a tag followed by a value. These ten rules from the encoding guide are enough to read one by hand.

01 / A

A Tag Is a Field Number and a Wire Type

Each field starts with a varint tag equal to the field number times 8, plus the wire type. So 0x08 is field 1 with wire type 0.

“What does tag 0x1a mean?”

02 / WIRE

Wire Type 0: Varint

Used for int32, int64, uint32, uint64, sint32, sint64, bool and enum. Each byte holds seven bits, lowest first, and a set high bit means another byte follows.

“How is 150 written as a varint?”

03 / NEGATIVE

Negative int32 Takes Ten Bytes

Negative int32 and int64 values are sign-extended to 64 bits, so -1 always costs ten bytes. That waste is why sint32 and sint64 exist.

“How many bytes does int32 -1 take?”

04 / ZIGZAG

ZigZag for sint32 and sint64

The signed types map 0, -1, 1, -2 to 0, 1, 2, 3, so small negatives stay short. The Also reads as column gives this zigzag reading for every varint.

“What does varint 3 mean as sint64?”

05 / WIRE

Wire Type 1: 64-Bit

fixed64, sfixed64 and double take exactly eight little-endian bytes. protoc prints them as a single hex number with the high byte first.

“Which double is 00 00 00 00 00 00 f0 3f?”

06 / WIRE

Wire Type 5: 32-Bit

fixed32, sfixed32 and float take four little-endian bytes. The same four bytes can be read as an integer or as an IEEE 754 float.

“Which float is 00 00 80 3f?”

07 / WIRE

Wire Type 2: Length-Delimited

A varint length is followed by that many bytes, used for strings, bytes, nested messages and packed repeated fields. Nothing on the wire says which of those it is.

“What does 12 07 start?”

08 / PACKED

Packed Repeated Fields

In proto3, repeated numbers are packed into one length-delimited field by default. The guide’s example 22 06 03 8e 02 9e a7 05 is field 4 holding 3, 270 and 86942.

“How many values are packed in 03 8e 02 9e a7 05?”

09 / WIRE

Wire Types 3 and 4: Groups

Start-group and end-group tags bracket a nested message in deprecated proto2 groups. Protobuf Editions reuses them for delimited message encoding.

“Which wire type ends a group?”

10 / FIELD

Field Numbers Run to 536,870,911

Valid numbers are 1 to 2^29 - 1, with 19000 to 19999 reserved for the protobuf implementation. Numbers 1 to 15 fit in a one-byte tag, so they suit the most frequent fields.

“Which field numbers get a one-byte tag?”

What the Bytes Can’t Tell You

Without the schema, some questions have more than one answer. This is how the decoder handles each.

Field Names

Names exist only in the .proto file, so the bytes give numbers alone. Match each number to the schema or a generated class to label the fields.

String, Bytes or Message

Wire type 2 carries all three. Nested mode treats a payload as a message when it isn’t readable text and parses cleanly, the same guess protoc --decode_raw makes, while Flat never guesses.

Signed or Unsigned

A varint could be an int, uint, sint, bool or enum. The value column shows it unsigned, and Also reads as adds the int64 and zigzag readings.

Integer or Floating Point

Fixed-width fields could be integers or IEEE floats, so both readings are listed. A round number such as 1 in the float column usually points to a double or float field.

Packed Numbers or a String

A packed repeated field is a length-delimited run of varints, which looks like a strange string. When the bytes split cleanly into varints, Also reads as lists them.

Missing Default Values

proto3 skips fields set to zero, empty or false, so an absent field may simply hold its default. The bytes alone can’t show whether it was ever set.

Protobuf Decoding Mistakes

Most failed decodes come from bytes that aren’t quite the message: a frame header, a length prefix or compression.

Tip 01

Strip the gRPC Frame First

gRPC puts a one-byte compression flag and a four-byte length before each message. Remove those 5 bytes, or the decoder reads them as a field.

Tip 02

Paste gRPC-Web Text as Base64

gRPC-Web text mode and many logs carry protobuf as Base64. Paste it as is, keeping in mind that text made only of hex digits is read as hex.

Tip 03

Remove Delimited Length Prefixes

Java’s writeDelimitedTo and similar APIs write a varint length before each message in a stream. Drop that prefix, or it decodes as a stray tag.

Tip 04

Don’t Trust Every Nested Guess

Short binary values can parse as a message by accident. If a nested block looks meaningless, switch to Flat and read the field as bytes.

Tip 05

Decompress Before Decoding

gzip-compressed messages start with 1f 8b, which decodes as an impossible wire type. Decompress the payload first, then paste it.

Tip 06

Negative int32 Values Look Huge

An int32 of -1 shows as 18446744073709551615 because it travels as a 64-bit varint. Read the int64 entry in Also reads as for the signed value.

Tip 07

Unknown Fields Reveal Schema Drift

Code generated from an older .proto keeps fields it doesn’t know as unknown fields. Raw decoding shows every number, which is how a mismatch becomes visible.

Tip 08

Map Fields Are Repeated Entries

A map in a .proto is sent as repeated entry messages, with the key as field 1 and the value as field 2. Expect one nested block per map entry.

When to Decode Protobuf Without a Schema

Whenever protobuf bytes turn up and the .proto file isn’t at hand.

Reading a gRPC Payload

Copy a message from a proxy or packet capture, remove the 5-byte gRPC header, and see every field number and value.

Checking What an Encoder Wrote

Confirm that a field went out with the number and type you meant, and that default values were left out as proto3 intends.

Debugging a Client and Server Mismatch

When two services disagree, decode the bytes to see which field numbers were really sent. A number missing from your .proto points straight at the mismatch.

Inspecting Stored Messages

Databases, caches and Kafka topics often hold serialized protobuf. Paste a value as hex or Base64 to see what it contains.

Studying an Undocumented Protocol

Mobile and IoT apps often speak protobuf with no published schema. Decoding several captures side by side shows which field numbers carry which data.

Learning the Wire Format

Paste the encoding guide’s examples and change one byte at a time to watch tags, varints and lengths respond. The rules stick once you see them.

Verifying Hand-Built Test Bytes

When a test needs a malformed or edge-case message, write the hex by hand and check that it decodes, or fails, exactly as intended.

Frequently Asked Questions