Protobuf Decoder Online

Decode Protocol Buffers wire format without a .proto schema

Use this free protobuf decoder to inspect binary Protocol Buffers payloads as an annotated field tree and JSON. Paste hex or base64, or drop a .pb file. No .proto required. works like protoc --decode_raw, entirely in your browser.

Decoding another binary format? Try the CBOR Decoder for RFC 8949 payloads, or the JWT Decoder for tokens.
From the blog
Request Waiting List Pattern in Distributed Systems

How a cluster node parks a client request while it collects quorum responses from other nodes, then answers at exactly the right moment

Read

Developer tools Latest posts Explainers

Hex tolerates 0x, spaces, commas, and newlines. Decoding runs as you type. No .proto needed.

Try These Examples

Click any sample to load it into the decoder above. All samples are hex.

Protobuf Wire Types

0 Varint int / uint / sint / bool / enum
1 64-bit fixed64 / sfixed64 / double
2 Length-delimited string / bytes / message / packed
5 32-bit fixed32 / sfixed32 / float

Tag Encoding

ConceptFormula / Notes
tag(field_number << 3) | wire_type encoded as a varint
Field numbers1–536,870,911 (field 0 is invalid)
Varint7 data bits per byte; high bit set means more bytes follow
Zigzag (sint)(n << 1) ^ (n >> 63) maps signed ints to unsigned varints efficiently
Length-delimitedVarint length, then that many bytes (string, bytes, nested message, or packed)
Groups 3 / 4Deprecated start/end group markers; labeled but not expanded

Understanding Protobuf Wire Format

What is Protocol Buffers?

Protocol Buffers (protobuf) is Google's language-neutral binary serialization format. You define messages in a .proto schema, compile code generators, and exchange compact binary payloads over gRPC, Kafka, and many APIs. Unlike JSON, the wire format does not include field names. only field numbers and wire types. so a schema-free decoder can recover structure and values, but not the human-readable names.

How to read a protobuf payload by hand

  • Read a tag varint: low 3 bits are the wire type; the rest is the field number
  • Wire type 0: read another varint (the value)
  • Wire type 1: read the next 8 bytes little-endian
  • Wire type 2: read a length varint, then that many bytes
  • Wire type 5: read the next 4 bytes little-endian
  • Repeat until the buffer is consumed

Example: 08 96 01 → tag 0x08 = field 1, wire type 0; value varint 0x96 0x01 = 150.

Decoding without a .proto (like protoc --decode_raw)

Running protoc --decode_raw < message.bin prints field numbers and values without a schema. This online tool does the same in your browser and adds:

  • Multiple type interpretations per field (uint vs sint vs bool, float vs fixed32, string vs nested message)
  • Recursive expansion of nested messages
  • Packed-repeated detection
  • JSON export keyed by field number

What you still cannot recover without the .proto: field names (user_id vs 1), enum symbolic names, and oneof groupings.

Where protobuf shows up

  • gRPC: request and response message bodies
  • Kubernetes / etcd / Envoy: many control-plane APIs use protobuf
  • Android / mobile: compact payloads between apps and backends
  • Observability: OpenTelemetry OTLP traces and metrics
  • Storage: protobuf blobs in Kafka topics, object stores, and databases

Protobuf vs JSON vs CBOR

  • Smaller than JSON: field numbers instead of names; binary ints and floats
  • Schema-first: evolving messages safely needs the .proto and field-number discipline
  • Not self-describing: unlike JSON or CBOR, you need the schema (or a wire-format viewer like this) to interpret payloads
  • CBOR is closer to self-describing JSON-in-binary. try our CBOR Decoder when that is what you have

Protobuf Decoder FAQ

Can I decode protobuf without a .proto file?

Yes. This tool performs wire-format analysis like protoc --decode_raw. It recovers field numbers, wire types, and values. Field names live only in the .proto and cannot be recovered from the bytes alone.

What are protobuf wire types?

Four wire types matter: 0 Varint (int/uint/sint/bool/enum), 1 64-bit (fixed64/sfixed64/double), 2 Length-delimited (string/bytes/message/packed), and 5 32-bit (fixed32/sfixed32/float). Types 3 and 4 (groups) are deprecated.

How do I decode a protobuf hex dump?

Paste the hex above with Hex mode selected. Spaces, commas, and 0x prefixes are fine. The Annotated Tree shows each field; Pretty JSON exports a structure keyed by field number.

How are length-delimited fields interpreted?

The decoder tries a nested-message parse first, then valid UTF-8 as a string, then a packed-repeated heuristic, and always offers a raw hex view.

Why do I see multiple interpretations for one field?

The wire type is not the full Protobuf type. A varint could be int64, uint64, sint64, or bool. Pick the reading that matches your schema or context.

What is the difference between this and protoc --decode_raw?

Same idea. schema-free wire walk. This tool runs in the browser, shows side-by-side interpretations, expands nested messages, and exports JSON. protoc --decode_raw is a CLI text dump.

Does this tool support gRPC payloads?

Yes for the message body. Strip the gRPC frame (1-byte flag + 4-byte big-endian length), then paste the remaining bytes. Gzip-compressed bodies are decompressed automatically when the browser supports DecompressionStream.

Is my data uploaded anywhere?

No. Decoding runs entirely in your browser. No payload, file, or decoded result is sent to any server.

How do I encode a protobuf message?

Encoding needs the schema (or generated stubs). This v1 tool focuses on decoding. Use protoc, your language's protobuf library, or a schema-aware encoder with your .proto file.