provectus/kafka-ui · error · JsonAvroConversionException
4002
4002
Error message
%s is not a part of enum symbols [%s]
What it means
When converting a JSON node to an Avro ENUM schema, convert() checks the string value against the schema's declared enum symbols (avroSchema.getEnumSymbols()). If the string is not one of the declared symbols, a JsonAvroConversionException with code 4002 is thrown. This enforces Avro's rule that enum values must exactly match a symbol defined in the schema.
Solutions
- Inspect the Avro schema's enum symbols and use one of the exact declared strings (case-sensitive).
- If the new value is legitimate, update/register a new schema version that includes the symbol.
- Normalize the payload value's casing/whitespace to match the schema symbols exactly.
Example fix
// before
{"state": "idle"} // schema symbols: ["IDLE", "RUNNING"]
// after
{"state": "IDLE"} Defensive patterns
Strategy: validation
Validate before calling
Set<String> symbols = new HashSet<>(avroSchema.getEnumSymbols());
if (!symbols.contains(jsonValue)) {
throw new IllegalArgumentException(jsonValue + " not in enum symbols " + symbols);
} Type guard
boolean isValidEnumValue(JsonNode node, Schema enumSchema) {
return node.isTextual() && enumSchema.getEnumSymbols().contains(node.textValue());
} Try / catch
try {
Object avro = JsonAvroConversion.convertJsonToAvro(json, schema);
} catch (JsonAvroConversionException e) {
// message contains '<value> is not a part of enum symbols' -> fix or remap the value
} Prevention
- Generate payload enums from the schema's symbol list, not free-form strings.
- Remember enum matching is case-sensitive and whitespace-sensitive.
- After schema evolution, re-validate old payloads against the new symbol set.
When it happens
Trigger: Producing a message whose field maps to an Avro enum type with a value not present in the schema's symbols list, e.g. JSON "state": "IDLE" when the schema only declares symbols ["RUNNING","STOPPED"]. Case differences ("running" vs "RUNNING") also trigger it.
Common situations: Schema evolution: a producer sends a value that was valid under an older schema version but is absent from the current one; typos or wrong casing when hand-writing payloads in kafka-ui's produce form.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- String is not a valid json
- Invalid format for webclient.maxInMemoryBufferSize
- seekTo should be set if seekType is
- Wrong seekTo argument format. See API docs for details
- Unexpected script result
AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08).
Data as JSON: /api/errors/b666b0bb973ead9c.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/jsonschema/JsonAvroConversion.java:90
}
case MAP -> {
assertJsonType(node, JsonNodeType.OBJECT);
var map = new LinkedHashMap<String, Object>();
var valueSchema = avroSchema.getValueType();
node.fields().forEachRemaining(f -> map.put(f.getKey(), convert(f.getValue(), valueSchema)));
yield map;
}
case ARRAY -> {
assertJsonType(node, JsonNodeType.ARRAY);
var lst = new ArrayList<>();
node.elements().forEachRemaining(e -> lst.add(convert(e, avroSchema.getElementType())));
yield lst;
}
case ENUM -> {
assertJsonType(node, JsonNodeType.STRING);
String symbol = node.textValue();
if (!avroSchema.getEnumSymbols().contains(symbol)) {
throw new JsonAvroConversionException("%s is not a part of enum symbols [%s]"
.formatted(symbol, avroSchema.getEnumSymbols()));
}
yield new GenericData.EnumSymbol(avroSchema, symbol);
}
case UNION -> {
// for types from enum (other than null) payload should be an object with single key == name of type
// ex: schema = [ "null", "int", "string" ], possible payloads = null, { "string": "str" }, { "int": 123 }
if (node.isNull() && avroSchema.getTypes().contains(NULL_SCHEMA)) {
yield null;
}
assertJsonType(node, JsonNodeType.OBJECT);
var elements = Lists.newArrayList(node.fields());
if (elements.size() != 1) {
throw new JsonAvroConversionException(
"UNION field value should be an object with single field == type name");
}
Map.Entry<String, JsonNode> typeNameToValue = elements.get(0);View on GitHub (pinned to 83b5a60cc0)