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

  1. Inspect the Avro schema's enum symbols and use one of the exact declared strings (case-sensitive).
  2. If the new value is legitimate, update/register a new schema version that includes the symbol.
  3. 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

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


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)