apache/kafka · error · IllegalArgumentException
The timeout cannot be negative.
Error message
The timeout cannot be negative.
What it means
Thrown by KafkaAdminClient.close(Duration) when the supplied timeout converts to a negative number of milliseconds. A negative duration is not a valid wait window, so the close path refuses it with IllegalArgumentException rather than treating it as zero or infinite; the client then remains un-closed. Note the close implementation also caps any positive timeout at one year.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/admin/KafkaAdminClient.java:723
if (defaultApiTimeoutMs < requestTimeoutMs) {
if (config.originals().containsKey(AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG)) {
throw new ConfigException("The specified value of " + AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG +
" must be no smaller than the value of " + AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG + ".");
} else {
log.warn("Overriding the default value for {} ({}) with the explicitly configured request timeout {}",
AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, defaultApiTimeoutMs,
requestTimeoutMs);
return requestTimeoutMs;
}
}
return defaultApiTimeoutMs;
}
@Override
public void close(Duration timeout) {
long waitTimeMs = timeout.toMillis();
if (waitTimeMs < 0)
throw new IllegalArgumentException("The timeout cannot be negative.");
waitTimeMs = Math.min(TimeUnit.DAYS.toMillis(365), waitTimeMs); // Limit the timeout to a year.
long now = time.milliseconds();
long newHardShutdownTimeMs = now + waitTimeMs;
long prev = INVALID_SHUTDOWN_TIME;
clientTelemetryReporter.ifPresent(ClientTelemetryReporter::initiateClose);
metrics.close();
while (true) {
if (hardShutdownTimeMs.compareAndSet(prev, newHardShutdownTimeMs)) {
if (prev == INVALID_SHUTDOWN_TIME) {
log.debug("Initiating close operation.");
} else {
log.debug("Moving hard shutdown time forward.");
}
client.wakeup(); // Wake the thread, if it is blocked inside poll().
break;
}
prev = hardShutdownTimeMs.get();
if (prev < newHardShutdownTimeMs) {View on GitHub (pinned to c31c9215e1)
Solutions
- Clamp the duration to non-negative before closing: admin.close(duration.isNegative() ? Duration.ZERO : duration).
- If you want an immediate non-blocking close, pass Duration.ZERO explicitly.
- Fix the deadline arithmetic so the computed remaining time can never go negative (use Math.max(0, remaining)).
Example fix
// before Duration remaining = deadlineInstant.minus(now); // can be negative admin.close(remaining); // throws IllegalArgumentException // after Duration remaining = Duration.between(Instant.now(), deadlineInstant); admin.close(remaining.isNegative() ? Duration.ZERO : remaining);
Defensive patterns
Strategy: validation
Validate before calling
Duration closeTimeout = /* computed */;
if (closeTimeout == null || closeTimeout.isNegative()) {
closeTimeout = Duration.ofSeconds(30); // sane default
}
admin.close(closeTimeout); Try / catch
try {
admin.close(closeTimeout);
} catch (IllegalArgumentException e) {
// 'The timeout cannot be negative.'
admin.close(); // fall back to no-arg / default timeout
} Prevention
- Clamp every Duration passed to close() to non-negative via Math.max(0, ...) or Duration.isNegative() guard.
- Prefer admin.close() (no-arg) when you have no specific shutdown budget; it uses a sane default.
- Watch for arithmetic on durations (subtraction, minus) that can silently produce negative values.
When it happens
Trigger: Calling admin.close(someDuration) where someDuration is negative — commonly admin.close(Duration.ofMillis(-1)) or a Duration computed by subtracting a later instant from an earlier one (e.g. deadline.minus(elapsed) going negative after the deadline already passed).
Common situations: Deadline-based code that computes remaining = deadline - now without clamping at zero; passing Duration.ZERO is fine but passing a negative Duration from a cancelled timer; refactoring that flipped the operand order in Duration.between(a, b).
Related errors
- Timeout needs to be greater than 0
- The specified value of default.api.timeout.ms must be no sma
- The TopicCollection: {topics} provided did not match any sup
- The TopicCollection: {topics} provided did not match any sup
- Cannot request fenced brokers from controller endpoint
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/a4ad16685d2b0156.json.
Report an issue: GitHub.