provectus/kafka-ui · error · ValidationException
UUID data should be 16 bytes, but it is
Error message
UUID data should be 16 bytes, but it is ${data.length} What it means
UuidBinarySerde deserializes 16-byte UUIDs (MSB-first or LSB-first per configuration). If the message payload is not exactly 16 bytes it cannot be a binary UUID, so ValidationException is thrown with the actual byte length.
Solutions
- Ensure producers write raw 16-byte UUIDs (UUID.nameUUIDFromBytes / writeLong msb+lsb), not string forms
- Restrict the serde's topic pattern to topics that truly contain binary UUIDs
- Check mostSignificantBitsFirst configuration matches the producer's byte order
Example fix
// before (producer) byte[] payload = uuid.toString().getBytes(); // after (producer) ByteBuffer bb = ByteBuffer.allocate(16); bb.putLong(uuid.getMostSignificantBits()); bb.putLong(uuid.getLeastSignificantBits()); byte[] payload = bb.array();
Defensive patterns
Strategy: validation
Validate before calling
if (data == null || data.length != 16) { /* skip topic or use fallback serde */ } Type guard
boolean isBinaryUuid(byte[] data) { return data != null && data.length == 16; } Try / catch
try { result = serde.deserialize(headers, data); } catch (ValidationException e) { result = fallbackSerde.deserialize(headers, data); } Prevention
- Producers must send raw 16-byte UUIDs, not string representations
- Configure serde topic patterns narrowly to UUID-only topics
- Confirm byte order (mostSignificantBitsFirst) with the producer team
When it happens
Trigger: deserializer invoked on a Kafka record whose byte array length != 16 (empty payload, string-encoded UUID, or other binary format).
Common situations: Applying the UUID serde to topics with mixed or non-UUID payloads; producer sending UUID as a 36-char string instead of 16 raw bytes; tombstone/null or truncated messages.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- 'name' property not set for serde
- Multiple serdes with same name
- className can't be set for built-in serde
- filePath can't be set for built-in serde types
- serde is not configured
AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08).
Data as JSON: /api/errors/57df7b12266e7c4b.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/serdes/builtin/UuidBinarySerde.java:71
return input -> {
UUID uuid = UUID.fromString(input);
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
if (mostSignificantBitsFirst) {
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
} else {
bb.putLong(uuid.getLeastSignificantBits());
bb.putLong(uuid.getMostSignificantBits());
}
return bb.array();
};
}
@Override
public Deserializer deserializer(String topic, Target type) {
return (headers, data) -> {
if (data.length != 16) {
throw new ValidationException("UUID data should be 16 bytes, but it is " + data.length);
}
ByteBuffer bb = ByteBuffer.wrap(data);
long msb = bb.getLong();
long lsb = bb.getLong();
UUID uuid = mostSignificantBitsFirst ? new UUID(msb, lsb) : new UUID(lsb, msb);
return new DeserializeResult(
uuid.toString(),
DeserializeResult.Type.STRING,
Map.of()
);
};
}
}
View on GitHub (pinned to 83b5a60cc0)