Schema-bound Protobuf message decoder
Inspect binary Protobuf with a supplied standalone proto2/proto3 schema and explicit message type, including 64-bit integers, field presence and unknown wire records.
- 1Add input
- 2Adjust settings
- 3Get your result
Tool input and files are processed in this browser without being uploaded.
Before you start
Read message bytes when you have their original schema. The report separates final values, explicit presence, declared defaults and wire sightings, and keeps the original binary for verification.
How to use this tool
- Select a binary file, or choose hex/base64 and paste encoded bytes.
- Paste the exact original .proto and fill the full message type.
- Review decoded values, presence, oneofs and unknown records; download the report and original bytes, then verify with the receiving schema.
Supported inputs and limits
One binary file up to 2 MiB, or pasted hex/base64 text up to 6 MiB whose decoded bytes stay within 2 MiB. ASCII spaces, tabs and line breaks may separate encoding text. Hex has no0x prefix; base64 requires standard characters, correct padding and canonical padding bits. A selected file takes precedence. Zero bytes can represent a valid empty message.
Paste a standalone proto2/proto3 .proto in the secondary field, up to 1 MiB,10000 descriptor JSON values and depth 32. Supply the explicit full message path, such as demo.Event; no type guessing or fetched import. Editions, services, extensions, declared groups and features overrides are unsupported. Names/paths are limited to 4096 characters; protected segments including __proto__, constructor and prototype reject to prevent renaming or prototype issues.
Wire lengths, tags, varints, UTF-8 strings and recursion budgets are checked before decoding. Wire traversal is capped at depth 32/20000 entries, including containers and packed elements; final decoded JSON at 20000 values/depth 32. Singular message fragments merge before final recursive required checks. Oneof last values and duplicate map keys follow Protobuf semantics. Invalid schema, truncation or missing final required fields fail atomically.
Output uses original protobuf field names. Every 64-bit integer is a decimal string; bytes are base64; enums retain numbers with names/aliases alongside. Float NaN, Infinity and negative zero use explicit strings. Defaults are reported without injecting absent fields; proto3 implicit zero values can disappear from decoded while wire sightings remain. Explicit proto2 byte defaults and unsafe/nonfinite numeric schema defaults are unsupported. Proto 3 explicit defaults reject.
Unknown fields, wrong wire types of known fields and closed proto2 unknown enum values include exact original offset/length/base64. A packed closed-enum record contains its entire original packed field, possibly including known values. Wire sightings can describe subsequently overwritten or discarded values. Inspection JSON is not lossless re-encoding; original binary stays complete. Total successful artifact size is10 MiB; table previews200 fields, JSON/CSV are complete. Schema is data; no user scripts, services or downloaded code execute. Trusted internal library decoder generation runs only in a standalone same-origin HTTP Worker, retaining page CSP.
Worked example
Example input
087b120161
Example options
{"secondary":"syntax = \"proto3\";\npackage demo;\nmessage Event { int64 seq = 1; bytes payload = 2; }","params":{"messageType":"demo.Event","encoding":"hex"}}Example output
{
"messageType": ".demo.Event",
"decoded": {
"seq": "123",
"payload": "YQ=="
},
"presence": [
{
"path": "$.seq",
"fieldNumber": 1,
"fieldType": "int64",
"presence": "implicit",
"present": true,
"entries": null,
"declaredDefault": "0"
},
{
"path": "$.payload",
"fieldNumber": 2,
"fieldType": "bytes",
"presence": "implicit",
"present": true,
"entries": null,
"declaredDefault": []
}
],
"oneofs": [],
"enumValues": [],
"enumDefinitions": {},
"wireOccurrences": [
{
"path": "$",
"offset": 0,
"length": 2,
"fieldNumber": 1,
"wireType": 0,
"fieldName": "seq",
"status": "known"
},
{
"path": "$",
"offset": 2,
"length": 3,
"fieldNumber": 2,
"wireType": 2,
"fieldName": "payload",
"status": "known"
}
],
"unknownFields": [],
"policy": "Decoded inspection representation; defaults are reported, not injected. Wire sightings can refer to overwritten values. Original binary retained; no lossless re-encoding claim."
}When something does not work
Confirm the exact schema, full message type, encoding and original bytes. Re-export a truncated message from its source rather than guessing missing bytes. Correct required content or unsupported schema scope and rerun the example; failures provide no partial artifacts.
Frequently asked questions
Are absent fields filled with defaults?
No. Presence and declaredDefault are separate. Decoded contains final actual values with normal proto3 implicit-default omission.
Why validate required fields after merging?
A singular submessage can occur in multiple fragments; later bytes can supply earlier missing required fields. Final merged messages are checked recursively.
Can I re-encode inspection JSON losslessly?
No. Original wire fragments and original.bin remain available, but normalized decoded values do not reconstruct the original serialization.
Documentation & further reading
Related tools
JSON formatting workspace
Format or minify strict JSON, sort object keys, and encode or decode strings while preserving raw number tokens.
Regex tester
Try a pattern and see what it matches in your text.
Compare text
See what changed, side by side.
HTML formatter
Format HTML indentation so its structure is easier to read.