PB Wire Format Utility

Protobuf Wire Format Decoder

Use this Protobuf Wire Format Decoder to inspect raw Protocol Buffers binary data from hexadecimal bytes. Decode field tags, field numbers, wire types, varints, fixed32, fixed64 and length-delimited values without requiring the original .proto schema.

✓ Field Tags ✓ Varint Decoder ✓ Fixed32 / Fixed64 ✓ Length-Delimited ✓ Wire-Type Validation
HEX
Decode Protobuf Wire Bytes
● Ready
Enter hexadecimal bytes separated by spaces, commas, colons or hyphens. Continuous hexadecimal data and 0x-prefixed bytes are also accepted.
Schema-free decoding: the protobuf wire stream contains field numbers and wire types, but it does not contain field names or enough type information to distinguish every possible schema type. For example, a length-delimited field may represent a string, raw bytes, an embedded message or packed repeated values. The tool shows what the wire bytes prove and labels optional interpretations separately.
Protobuf Wire Decode Result Decoded
Decoded Wire Records
Input Bytes
Fields / Records
Varint Fields
Length Fields
Fixed32 Fields
Fixed64 Fields
Group Tags
Reserved Field Nos.
# Offset Field Wire Type Tag Bytes Value / Length Payload Status
Byte-Level Decode Breakdown -
Normalized Input Bytes
-

What Is a Protobuf Wire Format Decoder?

A Protobuf Wire Format Decoder examines the binary representation produced by Protocol Buffers. Instead of requiring generated source code or a message schema, it reads the low-level tags and payload structures directly from the serialized bytes.

This is useful when debugging network captures, inspecting embedded-device messages, reverse-engineering your own protocol traffic, validating serializer output or understanding why a protobuf message occupies a particular number of bytes.

The decoder cannot reconstruct information that protobuf intentionally omits from the wire stream. Field names and exact declared types normally come from the message definition rather than from the serialized message itself.

How the Protobuf Wire Format Works

A protobuf binary message consists of a sequence of field records. Each record begins with a tag identifying the field number and the wire type.

record = tag + encoded payload

The wire type tells a parser how to find the end of the field value so unknown fields can be skipped even when the reader does not understand their schema.

Protobuf Tag Formula

The protobuf field tag combines the field number and wire type:

tag = (field_number << 3) | wire_type

To decode a tag:

wire_type = tag & 0x07 field_number = tag >> 3

The combined tag itself is stored as a protobuf varint.

Protobuf Wire Types

ID Wire Type Payload Format Common Schema Uses
0 Varint Variable-length integer int32, int64, uint32, uint64, sint32, sint64, bool, enum
1 Fixed64 8 bytes little-endian fixed64, sfixed64, double
2 Length-delimited Length varint + payload string, bytes, embedded messages, packed repeated fields
3 Start Group Group start marker Deprecated group encoding
4 End Group Group end marker Deprecated group encoding
5 Fixed32 4 bytes little-endian fixed32, sfixed32, float

Example: Decode 08 96 01

One of the standard protobuf encoding examples is:

08 96 01

First decode the tag byte:

0x08 = 8 decimal Field Number = 8 >> 3 = 1 Wire Type = 8 & 7 = 0 Field 1 Wire Type 0 — Varint

The remaining bytes 96 01 form a varint whose unsigned value is 150.

How Protobuf Varints Work

A protobuf varint stores seven payload bits in each byte. The most significant bit indicates whether another byte follows.

96 01 0x96: continuation bit = 1 0x01: continuation bit = 0 decoded value = 150

Small non-negative values therefore use fewer bytes than large values.

Unsigned Varint vs Signed and ZigZag Values

Wire type 0 alone does not tell a schema-free decoder whether the original field was uint32, uint64, int32, int64, sint32, sint64, bool or enum.

For that reason, this tool reports the raw unsigned varint value and a possible ZigZag interpretation. It does not claim that the ZigZag result is the field’s true application value unless the schema says the field is sint32 or sint64.

The same wire bytes can have different application meanings under different .proto field declarations.

Length-Delimited Protobuf Fields

Wire type 2 begins with a varint specifying the number of payload bytes that follow.

12 03 61 62 63 12 → Field 2, wire type 2 03 → Payload length = 3 bytes 61 62 63 → Raw payload bytes

Those bytes happen to represent the UTF-8 text abc, but wire type 2 is not automatically a string. It can also represent arbitrary bytes, embedded protobuf data or a packed repeated scalar field.

Why a Schema Is Needed for Complete Protobuf Decoding

The wire format contains enough information to safely separate fields, but it does not serialize the field names or full schema type declaration.

Wire Format Knows

Field number, wire type, encoded payload boundaries and raw values.

.proto Schema Knows

Field name, exact scalar type, enum definition, nested message type and repeated-field meaning.

This distinction is essential when inspecting protobuf data without its schema.

Fixed32 Protobuf Fields

Wire type 5 consumes exactly four bytes after the tag. The bytes are stored in little-endian order.

Depending on the schema, those same four bytes can represent fixed32, sfixed32 or an IEEE 754 single-precision floating-point value.

The decoder therefore reports the raw 32-bit unsigned value and also provides the corresponding float interpretation as supplemental information.

Fixed64 Protobuf Fields

Wire type 1 consumes exactly eight little-endian payload bytes. Possible schema types include fixed64, sfixed64 and double.

The decoder preserves the exact payload hex, calculates its unsigned 64-bit integer value and also shows the IEEE 754 double interpretation. The schema determines which interpretation is actually intended.

Protobuf Start Group and End Group

Wire types 3 and 4 represent the deprecated protobuf group mechanism. A Start Group tag begins a group associated with a field number, and a corresponding End Group tag closes it.

The decoder tracks group nesting and flags mismatched or unclosed group boundaries instead of silently ignoring them.

Protobuf Field Numbers

A protobuf field number is encoded in the upper portion of the tag after the lowest three wire-type bits are removed.

Field number zero is invalid. Protocol Buffer schemas also reserve field numbers 19000 through 19999 for the implementation, so the decoder marks a wire record in that range as a warning rather than inventing a normal schema field interpretation.

Why Small Field Numbers Use Less Space

Because the field number is part of a varint tag, smaller field numbers normally produce shorter tag encodings. Field numbers 1 through 15 can fit with the wire-type bits into a one-byte tag.

That is one reason frequently occurring protobuf fields are commonly assigned low field numbers.

UTF-8 Preview for Length-Delimited Fields

When a length-delimited payload is valid UTF-8 and contains readable text, the decoder shows a text preview. That preview is deliberately labeled as a preview rather than as proof that the field was declared as a protobuf string.

If the bytes are not valid readable UTF-8, the raw hexadecimal payload remains available without replacing binary data with misleading text.

Embedded Messages and Packed Fields

A length-delimited value may contain another protobuf message. It can also contain packed repeated primitive values. Without the message schema there is no reliable universal way to distinguish those cases merely from wire type 2.

This decoder therefore does not recursively declare every valid-looking byte sequence to be an embedded protobuf message. That avoids false decoding of ordinary byte arrays or strings.

Malformed Protobuf Data Detection

The decoder checks several common wire-format failures, including truncated varints, invalid wire types, field number zero, truncated fixed-width fields, declared length values that exceed the remaining input, and mismatched group markers.

When an unrecoverable structural error occurs, decoding stops at the byte offset where the problem was detected instead of guessing where the following field begins.

Common Uses for a Protobuf Wire Decoder

Network Debugging

Inspect protobuf payload bytes from packet captures or application logs.

Serializer Testing

Confirm that field numbers and low-level encoded values match expectations.

Embedded Systems

Analyze protobuf traffic from constrained devices without running a full protobuf development environment.

Schema Investigation

Identify wire-level field numbers and payload structures before applying a known message definition.

Common Protobuf Wire Format Mistakes

Reading the Tag as a Plain Byte

Tags themselves are varints and can occupy more than one byte.

Assuming Wire Type 2 Means String

Length-delimited values can represent several different protobuf schema types.

Ignoring Little Endian Fixed Values

Fixed32 and Fixed64 payloads are encoded little-endian.

Treating Every Varint as Unsigned Application Data

The schema may define signed, ZigZag, Boolean or enum semantics.

Expecting Field Names on the Wire

Serialized protobuf records contain field numbers, not source-code field names.

Assuming Field Order Is Meaningful

Parsers should not depend on a particular serialization order for fields.

Protobuf Wire Format Decoder FAQs

How do I decode protobuf binary data?
Read each protobuf tag as a varint, extract the low three bits as the wire type, shift the remaining bits to obtain the field number, and decode the following payload according to that wire type.
What does protobuf hex 08 96 01 mean?
Tag 08 represents field 1 with wire type 0. The following varint bytes 96 01 decode to unsigned value 150.
What is the protobuf tag formula?
The tag value is calculated as (field number << 3) OR wire type and is itself encoded as a varint.
What are the protobuf wire types?
The defined wire-type IDs are 0 Varint, 1 Fixed64, 2 Length-delimited, 3 Start Group, 4 End Group and 5 Fixed32.
What does wire type 0 mean?
Wire type 0 contains a protobuf varint. Several schema types can use that same wire representation.
What does wire type 1 mean?
Wire type 1 contains exactly eight little-endian payload bytes and is used by fixed64, sfixed64 and double fields.
What does wire type 2 mean?
Wire type 2 is length-delimited: a varint length is followed by exactly that many payload bytes.
What does wire type 5 mean?
Wire type 5 contains exactly four little-endian payload bytes and can represent fixed32, sfixed32 or float depending on the schema.
Can a protobuf decoder recover field names without the .proto file?
No. The binary wire format identifies fields by number. Field names are part of the message schema rather than the serialized record.
Can this tool tell whether a length-delimited field is a string?
It can show a readable UTF-8 preview when appropriate, but it cannot prove the field is declared as string without schema information.
Can wire type 2 contain another protobuf message?
Yes. It may represent an embedded message, but it may instead be string, bytes or packed repeated scalar data.
Why are protobuf integers variable length?
Varint encoding lets smaller non-negative numeric values use fewer bytes while still supporting larger integer ranges.
What is ZigZag encoding?
ZigZag maps signed integers to unsigned values so small negative and positive numbers can both be represented efficiently by varints. Protobuf sint32 and sint64 use ZigZag before varint encoding.
Are protobuf fixed32 values little-endian?
Yes. Fixed32 payload bytes are stored in little-endian order.
Are protobuf fixed64 values little-endian?
Yes. Fixed64 payload bytes are stored in little-endian order.
Is field number zero valid in protobuf?
No. A protobuf wire tag that decodes to field number zero is invalid.
Are protobuf field numbers 19000 through 19999 reserved?
Yes. That range is reserved for the Protocol Buffers implementation and should not be assigned to ordinary schema fields.
Does protobuf preserve field serialization order?
Applications should not rely on a guaranteed field serialization order. Parsers must be able to process fields regardless of their order in the wire stream.
Can this decoder detect malformed protobuf bytes?
Yes. It checks the structural boundaries it can determine from the wire format, including truncated varints, invalid wire-type IDs, truncated fixed fields and length-delimited payloads that exceed the available bytes.

Decode Raw Protocol Buffers Wire Data

Paste protobuf hexadecimal bytes to inspect tags, field numbers, wire types, varints, fixed-width values and length-delimited payloads while preserving the important distinction between wire-level facts and schema-dependent meaning.

Scroll to Top