t8y2/dbx · error · IllegalArgumentException
offsets must be an array
Error message
offsets must be an array
What it means
When committing consumer offsets, the agent reads an offsets parameter from the request's JSON params and requires it to be a JSON array of per-partition offset entries. If the offsets key is present but its value is not a JSON array, the agent throws IllegalArgumentException with this message. It is an input-validation error protecting the downstream deserialization loop that iterates the array.
Source
Thrown at agents/drivers/kafka/src/main/java/com/dbx/agent/kafka/KafkaAgent.java:1517
for (Map.Entry<TopicPartition, ListOffsetsResult.ListOffsetsResultInfo> entry : latest.entrySet()) {
offsets.put(entry.getKey(), new OffsetAndMetadata(entry.getValue().offset()));
}
}
}
admin.alterConsumerGroupOffsets(groupId, offsets)
.all().get(timeout, TimeUnit.MILLISECONDS);
return Collections.singletonMap("ok", true);
}
static Map<TopicPartition, OffsetAndMetadata> explicitConsumerGroupOffsets(JsonObject params, String topic) {
Map<TopicPartition, OffsetAndMetadata> offsets = new HashMap<>();
if (!params.has("offsets")) {
return offsets;
}
JsonElement offsetsElement = params.get("offsets");
if (!offsetsElement.isJsonArray()) {
throw new IllegalArgumentException("offsets must be an array");
}
JsonArray offsetArray = offsetsElement.getAsJsonArray();
if (offsetArray.isEmpty()) {
throw new IllegalArgumentException("offsets must contain at least one partition offset");
}
for (JsonElement element : offsetArray) {
if (!element.isJsonObject()) {
throw new IllegalArgumentException("each offset must be an object");
}
JsonObject value = element.getAsJsonObject();
int partition = nonNegativeExactInt(value, "partition");
long offset = nonNegativeExactLong(value, "offset");
TopicPartition topicPartition = new TopicPartition(topic, partition);
if (offsets.put(topicPartition, new OffsetAndMetadata(offset)) != null) {
throw new IllegalArgumentException("duplicate partition in offsets: " + partition);
}
}
return offsets;View on GitHub (pinned to c0390bff16)
Solutions
- Send offsets as a JSON array of partition-offset entries, e.g. "offsets": [{"topic":"t","partition":0,"offset":42,"metadata":""}].
- Fix the client serializer so a single offset is wrapped in a one-element array.
- Validate the payload shape before sending (JSON schema or a client-side check that offsets is an array).
- Check client/agent API version compatibility if an older format (object/map) was previously accepted.
Example fix
// before
{"offsets": {"topic": "events", "partition": 0, "offset": 42}}
// after
{"offsets": [{"topic": "events", "partition": 0, "offset": 42}]} Defensive patterns
Strategy: validation
Validate before calling
if (!params.has("offsets") || !params.get("offsets").isJsonArray()) {
throw new IllegalArgumentException("offsets must be a non-null JSON array");
} Type guard
boolean validOffsetsParam(JsonObject params) {
return params.has("offsets") && params.get("offsets").isJsonArray()
&& !params.getAsJsonArray("offsets").isEmpty();
} Try / catch
try {
agent.commitOffsets(params);
} catch (IllegalArgumentException e) {
if (String.valueOf(e.getMessage()).contains("offsets must be")) {
// log payload shape and reject/fix client request
} else throw e;
} Prevention
- Document and enforce the offsets payload schema (array of {topic, partition, offset}) client-side.
- Always wrap a single offset in an array before serializing.
- Add JSON schema validation at the API boundary to catch malformed payloads before they reach the agent.
- Version the request format when clients may send legacy map-shaped offsets.
When it happens
Trigger: Calling the agent's commit-offsets operation with a params object where "offsets" exists but holds a JSON object, string, number, or null instead of an array, e.g. {"offsets": {"topic": "t", "partition": 0, "offset": 42}}.
Common situations: Client serializing a single offset as an object instead of wrapping it in an array; a schema/API version mismatch where an older client sends a map-shaped offsets payload; hand-written tooling or scripts constructing the request JSON with the wrong shape.
Related errors
- Peek message count must be between 1 and " + MAX_PEEK_MESSAG
- ${name} must be a positive integer
- Kafka partition ${partition} does not exist for topic '${top
- Unsupported peek startPosition: ${value}
- partition must be non-negative
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/bd22518e57c7e218.
Report an issue: GitHub.