apache/kafka · error · SchemaException

{} is not a long

Error message

{} is not a long

What it means

Thrown by VARLONG.validate() when the object passed to the schema validator is not a java.lang.Long. VARLONG is the zig-zag variable-length 64-bit integer type used in modern Kafka APIs; validate() is the type-coercion gate invoked during Struct/Schema validation to ensure the value matches the declared type before serialization.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/protocol/types/Type.java:1138

        }
    };

    public static final DocumentedType VARLONG = new DocumentedType() {
        @Override
        public void write(ByteBuffer buffer, Object o) {
            ByteUtils.writeVarlong((Long) o, buffer);
        }

        @Override
        public Long read(ByteBuffer buffer) {
            return ByteUtils.readVarlong(buffer);
        }

        @Override
        public Long validate(Object item) {
            if (item instanceof Long)
                return (Long) item;
            throw new SchemaException(item + " is not a long");
        }

        public String typeName() {
            return "VARLONG";
        }

        @Override
        public int sizeOf(Object o) {
            return ByteUtils.sizeOfVarlong((Long) o);
        }

        @Override
        public String documentation() {
            return "Represents an integer between -2<sup>63</sup> and 2<sup>63</sup>-1 inclusive. " +
                    "Encoding follows the variable-length zig-zag encoding from " +
                    " <a href=\"https://code.google.com/apis/protocolbuffers/docs/encoding.html\"> Google Protocol Buffers</a>.";
        }
    };

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Ensure the value is a long: cast or wrap explicitly with Long.valueOf(...) / suffix literals with L before placing into the Struct.
  2. When mapping from another schema (Avro, JSON), coerce the source type to java.lang.Long before validation.
  3. For offset/timestamp fields, use the API's typed setters that take long primitives rather than Object.
  4. Add an assertion in your builder code that the field is instanceof Long before calling the schema.

Example fix

// before: int autoboxes to Integer, validate fails
struct.set("OFFSET", 5); // VARLONG.validate throws "5 is not a long"

// after: explicit long
struct.set("OFFSET", 5L);
Defensive patterns

Strategy: type-guard

Validate before calling

// Narrow before calling VARLONG.validate so the error never fires.
if (!(item instanceof Long)) {
    throw new IllegalArgumentException(
        "Expected Long, got " + (item == null ? "null" : item.getClass().getName()));
}
Long value = (Long) item; // safe
org.apache.kafka.common.protocol.types.Type.VARLONG.validate(item);

Type guard

// Java type guard / narrowing predicate.
static boolean isLong(Object o) {
    return o instanceof Long;
}

// Usage:
if (isLong(item)) {
    Long v = (Long) item;
    org.apache.kafka.common.protocol.types.Type.VARLONG.validate(v);
} else {
    throw new IllegalArgumentException("VARLONG requires Long, got " + (item == null ? "null" : item.getClass()));
}

Prevention

When it happens

Trigger: Calling VARLONG.validate(item) (directly or via Schema.validate on a struct containing a VARLONG field) where item is an Integer, BigInteger, String, or any non-Long. Commonly reached when populating a Struct with a primitive int or a boxed Integer for a field declared as VARLONG.

Common situations: Passing an int literal into a Struct for a VARLONG field (autoboxes to Integer, not Long). Cross-system data mapping (Avro/Protobuf -> Kafka Struct) that yields BigInteger or String. Unit tests that hand-build Structs without casting offsets/timestamps to long.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/032f9c5007f1077a.json. Report an issue: GitHub.