provectus/kafka-ui · error · JsonAvroConversionException
String is not a valid json
Error message
String is not a valid json
What it means
JsonAvroConversion.convertJsonToAvro wraps Jackson's readTree in a try/catch and rethrows any JsonProcessingException as a JsonAvroConversionException with message "String is not a valid json". It means the payload string passed for JSON-to-Avro conversion could not be parsed as JSON at all, before any Avro schema validation happens. This is a client-side input format error, not a schema or Kafka problem.
Solutions
- Validate the payload with any JSON parser (e.g. MAPPER.readTree(json) or JSON.parse) before submitting; fix syntax errors (quote keys, use double quotes, remove trailing commas).
- Check that the string was not truncated or double-escaped during copy/paste or transport (e.g. nested quotes escaped twice).
- If generating JSON programmatically, use a serializer (Jackson ObjectMapper.writeValueAsString) instead of string concatenation.
Example fix
// before
String json = "{name: 'sensor-1', value: 42}"; // invalid: single quotes, unquoted key
Object avro = JsonAvroConversion.convertJsonToAvro(json, schema);
// after
String json = "{\"name\": \"sensor-1\", \"value\": 42}";
Object avro = JsonAvroConversion.convertJsonToAvro(json, schema); Defensive patterns
Strategy: validation
Validate before calling
try {
new ObjectMapper().readTree(jsonString);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Payload is not valid JSON: " + e.getOriginalMessage());
} Try / catch
try {
Object avro = JsonAvroConversion.convertJsonToAvro(json, schema);
} catch (JsonAvroConversionException e) {
if (e.getMessage().equals("String is not a valid json")) {
// surface a JSON syntax error to the user / reject the record
}
} Prevention
- Always validate JSON with a parser before submitting payloads.
- Generate JSON with a serializer, never by string concatenation.
- When copying payloads from logs, check for truncation and re-escaping.
When it happens
Trigger: Calling convertJsonToAvro(jsonString, avroSchema) with a string that is not syntactically valid JSON, e.g. raw Java/JavaScript object literal like {name: 'x'} (unquoted keys, single quotes), trailing commas, truncated JSON, or an empty/whitespace string.
Common situations: Users pasting a record payload into the kafka-ui 'produce message' form with quotes stripped or copied from a log line; string-concatenated JSON built by hand; payloads that were serialized with Avro/protobuf and pasted as-is instead of valid JSON.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- ' ' is not valid json
- 4002
- Invalid format for webclient.maxInMemoryBufferSize
- seekTo should be set if seekType is
- Wrong seekTo argument format. See API docs for details
AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08).
Data as JSON: /api/errors/fedcd4f115167058.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/jsonschema/JsonAvroConversion.java:56
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
// json <-> avro
public class JsonAvroConversion {
private static final JsonMapper MAPPER = new JsonMapper();
private static final Schema NULL_SCHEMA = Schema.create(Schema.Type.NULL);
private static final String FORMAT = "format";
private static final String DATE_TIME = "date-time";
// converts json into Object that is expected input for KafkaAvroSerializer
// (with AVRO_USE_LOGICAL_TYPE_CONVERTERS flat enabled!)
public static Object convertJsonToAvro(String jsonString, Schema avroSchema) {
JsonNode rootNode = null;
try {
rootNode = MAPPER.readTree(jsonString);
} catch (JsonProcessingException e) {
throw new JsonAvroConversionException("String is not a valid json");
}
return convert(rootNode, avroSchema);
}
private static Object convert(JsonNode node, Schema avroSchema) {
return switch (avroSchema.getType()) {
case RECORD -> {
assertJsonType(node, JsonNodeType.OBJECT);
var rec = new GenericData.Record(avroSchema);
for (Schema.Field field : avroSchema.getFields()) {
if (node.has(field.name()) && !node.get(field.name()).isNull()) {
rec.put(field.name(), convert(node.get(field.name()), field.schema()));
}
}
yield rec;
}
case MAP -> {
assertJsonType(node, JsonNodeType.OBJECT);View on GitHub (pinned to 83b5a60cc0)