An unwrapped union
Plain JSON that the console producer rejects, because Avro JSON wraps union values in their type
{"id":1,"email":"a@b.com"}Convert between the Avro JSON encoding and plain JSON, in either direction, against a schema. The difference is union wrapping, which is what the console producer and the REST proxy insist on and what a hand-written line gets wrong.
Detection tries the Avro form first, because that is the form the wrapping exists to disambiguate. A document that is valid as both is reported rather than resolved.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Convert. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
Plain JSON that the console producer rejects, because Avro JSON wraps union values in their type
{"id":1,"email":"a@b.com"}The same record with the union wrapped, which is what Avro tooling expects
{"id":1,"email":{"string":"a@b.com"}}These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
Avro JSON wraps a non-null union value in its type name. Plain JSON is rejected by the console producer with a message about the union.
Instead:Wrap it: {"string":"value"}, or null for the null branch.
Bytes are encoded as ISO-8859-1 strings and unions are wrapped. Round-tripping through a normal JSON tool corrupts both.
Instead:Use the Avro JSON encoding when talking to Avro tooling, and plain JSON everywhere else.
Avro JSON requires every field to be present, defaults included. Defaults apply to schema resolution, not to the encoding.
Instead:Write every field.
Avro defines its own JSON encoding, and it is not the JSON you would write by hand. The whole difference is union wrapping, and it is the reason kafka-avro-console-producer rejects a line that looks perfectly correct.
In the Avro JSON encoding every non-null union branch is a one-key object named for the branch's type: {"string": "abc"}. Only the null branch is written bare, as null. That is what makes a union unambiguous in JSON, since a plain value cannot say which branch was meant when two branches share a JSON shape.
// Avro JSON
{"note": {"string": "hi"}}
// plain JSON
{"note": "hi"} This is where a hand-written line usually goes wrong. The key is com.example.orders.Money, not Money, and the parser's error is about an unknown union branch rather than about the name being short. Anything without a namespace uses the bare name, which is why it works in a tutorial and stops working the moment a namespace is added.
Both are written as a JSON string whose code points are the byte values, so a byte of 0xFF is the character U+00FF. That is the specification, and it means a payload of arbitrary bytes round-trips through JSON while looking like nonsense. Both forms on this page do the same thing here, so the plain form and the Avro form differ in union wrapping and in nothing else.
A union of int and long, or of two records, has branches that share a JSON shape, so converting from plain JSON means guessing which was meant. This page picks the first branch that fits and says so rather than doing it quietly. If a document like that is going anywhere near a producer, it has to be in the Avro form.
Reading JSON, a missing field with a default is filled in. In the binary encoding there is nothing to omit: every field is written in order with no names and no lengths, so a value has to exist for each one whether or not the schema has a default. That asymmetry catches people moving between the two.
Whether the schema is the right one. Both forms are checked against the schema you paste and nothing else, so a document that converts cleanly is well-formed for that schema and says nothing about whether that is the schema on the topic. Everything runs in your browser.