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

  1. Send offsets as a JSON array of partition-offset entries, e.g. "offsets": [{"topic":"t","partition":0,"offset":42,"metadata":""}].
  2. Fix the client serializer so a single offset is wrapped in a one-element array.
  3. Validate the payload shape before sending (JSON schema or a client-side check that offsets is an array).
  4. 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

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


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/bd22518e57c7e218. Report an issue: GitHub.