t8y2/dbx · error · IllegalArgumentException

offset must be non-negative

Error message

offset must be non-negative

What it means

In validatePeekRequest, an explicit offset is only meaningful when startPosition is "offset" (the legacy path without startPosition also allows a bare offset). If startPosition is earliest/latest and an offset is also provided, the driver throws this IllegalArgumentException because the two settings conflict.

Source

Thrown at agents/drivers/kafka/src/main/java/com/dbx/agent/kafka/KafkaAgent.java:2128

            case "latest" -> PeekStartPosition.LATEST;
            case "offset" -> PeekStartPosition.OFFSET;
            default -> throw new IllegalArgumentException("Unsupported peek startPosition: " + value);
        };
    }

    static void validatePeekRequest(
        PeekStartPosition startPosition,
        boolean explicitStartPosition,
        Integer partition,
        Long offset
    ) {
        if (partition != null && partition < 0) {
            throw new IllegalArgumentException("partition must be non-negative");
        }
        if (!explicitStartPosition) {
            // Older clients used offset directly without a startPosition field.
            if (offset != null && offset < 0) {
                throw new IllegalArgumentException("offset must be non-negative");
            }
            return;
        }
        if (startPosition != PeekStartPosition.OFFSET) {
            if (offset != null) {
                throw new IllegalArgumentException("offset is only supported when startPosition is offset");
            }
            return;
        }
        if (offset == null) {
            throw new IllegalArgumentException("offset is required when startPosition is offset");
        }
        if (offset < 0) {
            throw new IllegalArgumentException("offset must be non-negative when startPosition is offset");
        }
    }

    static Long requestedPeekOffset(

View on GitHub (pinned to c0390bff16)

Solutions

  1. Remove the offset field from the request when startPosition is earliest or latest.
  2. If you need a specific offset, set startPosition to "offset" and supply the offset.
  3. Ensure your serialization layer omits null/unused fields instead of sending defaults.

Example fix

// before
{"startPosition": "latest", "offset": 42}

// after
{"startPosition": "latest"}
Defensive patterns

Strategy: validation

Validate before calling

if (offset != null && !"offset".equals(startPosition)) {
    throw new IllegalArgumentException("offset requires startPosition=offset");
}

Type guard

boolean isConsistentPeekRequest(String startPosition, Long offset) {
    return offset == null || "offset".equals(startPosition);
}

Try / catch

try {
    return agent.peek(conn, req);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("offset is only supported when startPosition is offset")) {
        req.offset = null;
        return agent.peek(conn, req);
    } else throw e;
}

Prevention

When it happens

Trigger: Sending a peek request with startPosition="latest" (or "earliest") while also including an offset field; a client library that always serializes a default offset of 0 alongside startPosition.

Common situations: Persisted request templates that kept a stale offset field after switching startPosition to latest; ORM/serializer defaults populating offset automatically; copy-paste between the offset-based and earliest/latest request styles.

Related errors


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