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

  1. Ensure producers write raw 16-byte UUIDs (UUID.nameUUIDFromBytes / writeLong msb+lsb), not string forms
  2. Restrict the serde's topic pattern to topics that truly contain binary UUIDs
  3. 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

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


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)