Schema Sample Data
Turn a schema into realistic test data. Deterministic, so the same schema always gives the same JSON and it can go straight into a fixture.
Avro's resolution rules are specified, so this gives a definite answer: backward means a reader on the new schema can read old data, forward means a reader on the old schema can read new data, and full means both. Protobuf has three different notions of "compatible" and a change can be safe under one while breaking another — renaming a field is invisible on the wire and fatal for protobuf JSON. All three are reported separately rather than blended into one verdict.
{{ error }}
They differ only in documentation, aliases, defaults or formatting — the canonical
forms are identical, so nothing about reading data changes.These are the same schema
{{ v.label }}
{{ v.ok ? v.okText : v.badText }}
{{ grp.label }}{{ grp.issues.length }}
- {{ d.path }} — {{ d.message }}
No differences that affect compatibility.
A protobuf payload is decodable without its schema — every field carries its
number and wire type. What it does not carry is names or declared types, so the same bytes
genuinely have several valid readings. Every plausible one is shown rather than one
confident guess. Paste a .proto below to resolve the names.
Add a .proto to resolve field names (optional)
{{ error }}
{{ framing.note }}
- {{ w }}
Field number{{ schemaNotes.unknown.length === 1 ? '' : 's' }} {{ schemaNotes.unknown.join(', ') }} appear in the payload but not in the schema — that is what version skew looks like on the wire.
Not present in this payload: {{ schemaNotes.missing.join(', ') }}. In proto3 an unset field and a zero value are indistinguishable, so absence here does not prove it was never set.
-
{{ f.number }}
{{ f.name }}
{{ f.wireName }}
declared {{ f.declaredType }}
- {{ r.as }}{{ r.value }}
Nothing decoded from those bytes.
Deterministic on purpose — the same schema always produces the same sample, so it can go straight into a fixture or a test without changing under you. Output follows protobuf's canonical JSON mapping, which is where the surprises live: lowerCamelCase keys, 64-bit integers as strings, enums as symbol names, and Timestamp as a string rather than an object.
{{ sampleText || 'Generated JSON appears here…' }}
{{ error }}
Everything is parsed and analysed entirely in your browser. Nothing you paste is ever uploaded to a server.
Deterministic, so it can go in a test
The same schema always produces exactly the same JSON here. That is the difference between sample data you can commit as a fixture and sample data you have to regenerate every time something changes. Nothing is random, and no external word list or fake-data corpus is used — the value chosen for a field comes from its declared type, its default if it has one, and a hint taken from its name.
Defaults win
A field with a declared default gets that exact value, because that is what a real reader would supply for it. Only fields without one get a generated value. A union picks its first non-null branch, since a sample full of nulls demonstrates nothing about the shape of your data — unless the field explicitly defaults to null, which is respected.
Protobuf JSON is not what most people expect
The canonical mapping renames fields to lowerCamelCase, encodes 64-bit integers as
strings (they exceed what a JSON number represents exactly), writes enums as their
symbol names rather than numbers, and represents Timestamp and
Duration as strings rather than objects. The sample follows all of that, because a
sample that looked like the .proto would be convenient and wrong.
Recursive schemas do not hang
A type that refers to itself — a tree node, a linked list — is legitimate and common. Generation stops when it revisits a type, so you get one level of the structure rather than an unresponsive page.
Checking a schema rather than filling it?
Use the Avro Schema Viewer, which validates defaults and logical types, or the Schema Compatibility Checker before you deploy a change.
Frequently asked questions
Why is the output the same every time?
Deliberately. Random sample data cannot be committed to a test as a fixture, because the next run produces something different. The same schema always produces the same JSON here, so you can paste it straight into a test and it stays valid.
Does it respect my defaults?
Yes — a field with a declared default gets exactly that value rather than a generated one, since the default is what a real reader would supply. Fields without one get a value chosen to match the type, and where the field name hints at a shape such as email, url, uuid or city, the value follows that hint.
Why does my int64 come out as a string in the Protobuf output?
Because that is what protobuf's canonical JSON mapping specifies. 64-bit integers exceed what JSON numbers can represent exactly, so they are encoded as strings. The same mapping turns Timestamp and Duration into strings rather than objects, writes enums as their symbol names, and renames fields to lowerCamelCase — all of which surprise people the first time they see real protobuf JSON, which is why the sample shows it correctly rather than conveniently.
How does it handle a union or a nullable field?
It picks the first non-null branch, because a sample full of nulls demonstrates nothing about the shape of your data. If the field has an explicit null default, that is respected instead.
What about a schema that refers to itself?
Recursive types are common and legitimate — a tree node, a linked list. Sampling stops when it revisits a type rather than recursing forever, so you get one level of the structure instead of a hang.
Is my schema uploaded anywhere?
No. Parsing and generation both run in your browser.