Neatbo.

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.

Browser-local processingInputProtobuf binary / .proto schemaOutputInspection JSON / CSV / Original binaryUp to 2 MiB per file · File limit: 1
  1. 1Add input
  2. 2Adjust settings
  3. 3Get your result

Tool input and files are processed in this browser without being uploaded.

Your input

Inputs are kept temporarily in this tab when switching tools. Refreshing or closing clears them; large results may need to be regenerated.

⌘ / Ctrl + Enter to run

or drag and drop it here

Files stay on this device. Your originals stay unchanged.

.bin · .pb · .protobuf · .dat

Up to 2 MiB per file · File limit: 1

    0 characters · 0 bytes
    Options

    Complete the required options first. You can keep the defaults for the rest.

    Preparing the tool…

    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

    1. Select a binary file, or choose hex/base64 and paste encoded bytes.
    2. Paste the exact original .proto and fill the full message type.
    3. 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