apache/kafka · error · DisconnectException

NetworkClient is no longer active, state is {state}

Error message

NetworkClient is no longer active, state is {state}

What it means

Thrown as a DisconnectException by NetworkClient.ensureActive() when an operation is attempted while the NetworkClient state is not ACTIVE (i.e. CLOSING or CLOSED). ensureActive() guards every send/poll path so that work scheduled after initiateClose() or close() fails fast instead of silently dropping requests. The state value in the message indicates how far through shutdown the client has progressed.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/NetworkClient.java:795

    public void wakeup() {
        this.selector.wakeup();
    }

    @Override
    public void initiateClose() {
        if (state.compareAndSet(State.ACTIVE, State.CLOSING)) {
            wakeup();
        }
    }

    @Override
    public boolean active() {
        return state.get() == State.ACTIVE;
    }

    private void ensureActive() {
        if (!active())
            throw new DisconnectException("NetworkClient is no longer active, state is " + state);
    }

    /**
     * Close the network client
     */
    @Override
    public void close() {
        state.compareAndSet(State.ACTIVE, State.CLOSING);
        if (state.compareAndSet(State.CLOSING, State.CLOSED)) {
            cancelBootstrapResolution();
            ThreadUtils.shutdownExecutorServiceQuietly(bootstrapExecutor, 1, TimeUnit.SECONDS);
            this.selector.close();
            this.metadataUpdater.close();
            if (telemetrySender != null)
                telemetrySender.close();
        } else {
            log.warn("Attempting to close NetworkClient that has already been closed.");
        }

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Do not invoke client operations after close(); track lifecycle and gate callers with an AtomicBoolean 'closed' flag.
  2. Ensure close() runs after all in-flight requests complete (drain, await, then close).
  3. Give each long-lived owner its own client instead of sharing one closable instance across independent components.
  4. Catch DisconnectException at the call site and treat it as a terminal signal to stop / rebuild the client.

Example fix

// before
producer.send(record);
producer.close();   // a concurrent sender thread may now hit ensureActive()
// after
producer.close(Duration.ofSeconds(10)); // close waits for outstanding sends to complete
// or guard callers:
if (!closed.get()) producer.send(record);
Defensive patterns

Strategy: validation

Validate before calling

// Guard every blocking call with an active-state check.
if (!networkClient.active()) {
    throw new IllegalStateException(
        "NetworkClient is not active (state=" + networkClient.state() + "); cannot send or poll.");
}
// Only now proceed to poll/send/awaitReady.

Type guard

// Treat 'active' as a precondition predicate, not an assumption.
public static boolean isUsable(KafkaClient client) {
    return client != null && client.active();
}
// Usage:
if (!isUsable(networkClient)) { /* re-create client or fail the operation */ }

Try / catch

try {
    networkClient.poll(...);
} catch (org.apache.kafka.common.errors.DisconnectException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("NetworkClient is no longer active")) {
    // client was closed (initiateClose/close ran). Rebuild the client or fail the operation;
    // retrying on the same instance is NOT safe.
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling client.send(), client.poll(), or any ensureActive-guarded method on a KafkaProducer/KafkaConsumer/AdminClient/KafkaClient after close() or initiateClose() has run. Common in shared-client singletons where one thread closes the client while another issues a request; in @PreDestroy / shutdown hooks racing with in-flight work; and in test teardown that does not wait for outstanding calls to drain.

Common situations: Producer/Consumer/Admin closed in a different thread than the caller; bean lifecycle (Spring) destroying the client bean mid-request; reusing a cached client after a broker-driven reconnect failure that triggered close; shutdown hook invoked while the app is still serving traffic.

Related errors


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