apache/iceberg · error · IllegalArgumentException
Cannot convert to UUID
Error message
Cannot convert to UUID: ${value.getClass().getName()} What it means
RecordConverter.convertUUID throws this IllegalArgumentException when a Kafka Connect source value cannot be converted to an Iceberg UUID column value. Only java.lang.String (parsed via UUID.fromString) and java.util.UUID are accepted; any other type fails. It signals a type mismatch between the Kafka Connect record schema and the Iceberg table schema.
Solutions
- Change the Kafka Connect schema for that field to string (SchemaBuilder.string()) so convertUUID parses it with UUID.fromString
- Pre-convert the value to java.util.UUID or String in an SMT before the sink connector
- If data is binary UUID bytes, decode to a UUID string (e.g. 16-byte MSB/LSB hex) in a custom converter
- Check the RecordConverter subclass/field mapping so the UUID column is not bound to the wrong Connect field
Example fix
// before Schema uuidSchema = SchemaBuilder.bytes().build(); // yields byte[] value // after Schema uuidSchema = SchemaBuilder.string().build(); // "123e4567-e89b-..." parses as UUID
Defensive patterns
Strategy: type-guard
Validate before calling
// before sinking
if (value != null && !(value instanceof String || value instanceof UUID)) {
throw new IllegalStateException("Field 'id' must be String or UUID, got: " + value.getClass());
} Type guard
static boolean isUuidCompatible(Object v) {
return v == null || v instanceof String || v instanceof UUID;
} Try / catch
try {
converter.convertValue(value, Types.UUID_TYPE);
} catch (IllegalArgumentException e) {
log.error("UUID conversion failed, check Connect schema for field", e);
// route to DLQ or coerce: UUID.fromString(String.valueOf(value))
} Prevention
- Declare UUID fields as string schema in Kafka Connect
- Never let schemaless mode feed UUID columns
- Add a unit test asserting record schemas match the Iceberg table schema
- Use UUID string canonical form (UUID.toString) in producers
When it happens
Trigger: A Variant/UUID field receives a Number, byte[], Map, or Struct value instead of a String or UUID; e.g. a connector config or schema maps a UUID Iceberg column to a Kafka bytes or int field.
Common situations: Kafka Connect JSON converter loses native UUID types and delivers a type the sink schema doesn't declare as string; custom SMTs or schema registry schemas typed a UUID field as bytes/int8; source databases export UUIDs as binary via JDBC.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Cannot convert date
- Cannot convert time
- Cannot convert timestamp
- Cannot convert timestamptz
- Cannot convert to binary
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/71aaf19a78b31ce2.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/data/RecordConverter.java:515
} else if (value instanceof Struct) {
Struct struct = (Struct) value;
byte[] data = config.jsonConverter().fromConnectData(null, struct.schema(), struct);
return new String(data, StandardCharsets.UTF_8);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
throw new IllegalArgumentException("Cannot convert to string: " + value.getClass().getName());
}
protected Object convertUUID(Object value) {
UUID uuid;
if (value instanceof String) {
uuid = UUID.fromString((String) value);
} else if (value instanceof UUID) {
uuid = (UUID) value;
} else {
throw new IllegalArgumentException("Cannot convert to UUID: " + value.getClass().getName());
}
if (FileFormat.PARQUET
.name()
.toLowerCase(Locale.ROOT)
.equals(config.writeProps().get(TableProperties.DEFAULT_FILE_FORMAT))) {
return UUIDUtil.convert(uuid);
} else {
return uuid;
}
}
protected ByteBuffer convertBase64Binary(Object value) {
if (value instanceof String) {
return ByteBuffer.wrap(Base64.getDecoder().decode((String) value));
} else if (value instanceof byte[]) {
return ByteBuffer.wrap((byte[]) value);
} else if (value instanceof ByteBuffer) {View on GitHub (pinned to 86d9c8fc54)