{"id":"8a594db309a7a005","repo":"apache/kafka","slug":"the-consumer-background-thread-is-not-running-and","errorCode":null,"errorMessage":"The consumer background thread is not running and cannot process requests.","messagePattern":"The consumer background thread is not running and cannot process requests\\.","errorType":"exception","errorClass":"KafkaException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/events/ApplicationEventHandler.java","lineNumber":176,"sourceCode":"                () -> log.warn(\"The application event handler was already closed\")\n        );\n    }\n\n    /**\n     * Best-effort check that the consumer network thread is still alive. If the thread has\n     * already terminated (due to a failure or shutdown), it will never process any events from\n     * the queue. Rather than blocking indefinitely or timing out with a misleading error, this\n     * fails fast with a clear error message.\n     *\n     * <p>Note: this is inherently racy — the thread could die between this check and the\n     * subsequent {@code applicationEventQueue.add()}. That narrow window is acceptable because\n     * any subsequent call to {@code add()} will detect the dead thread immediately.\n     *\n     * @throws KafkaException if the background thread is not alive\n     */\n    private void ensureNetworkThreadAlive() {\n        if (networkThread == null || !networkThread.isAlive()) {\n            throw new KafkaException(\n                \"The consumer background thread is not running and cannot process requests.\");\n        }\n    }\n}\n","sourceCodeStart":158,"sourceCodeEnd":181,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/events/ApplicationEventHandler.java#L158-L181","documentation":"Thrown by ApplicationEventHandler.ensureNetworkThreadAlive() when the async consumer's background network thread is null or no longer alive. The new (threaded) consumer delegates all work to that thread via an event queue; if the thread has terminated it will never drain the queue, so any further consumer call would either block indefinitely or surface a misleading timeout. This check fails fast with a clear message instead. Note the code comment explicitly calls the check racy-by-design — the thread could die right after the check, but the subsequent queue add() would then detect it.","triggerScenarios":"Any consumer operation that goes through ApplicationEventHandler.add() (poll, commitSync/Async, subscribe, unsubscribe, seek, position, offsetsForTimes, listOffsets, etc.) after the network thread has died or before/after close(). Triggered specifically when networkThread == null || !networkThread.isAlive().","commonSituations":"Reusing a KafkaConsumer instance after close() has been called; an uncaught exception or OutOfMemoryError killing the network thread silently; JVM thread limits preventing the thread from starting; calling consumer methods from a different thread after the consumer's owning thread was interrupted; framework code (Spring @KafkaListener, Vert.x) that pools/rewires consumer instances.","solutions":["Do not reuse the KafkaConsumer after calling close() — create a fresh instance.","Inspect logs immediately preceding this error for the original Throwable that killed the network thread (it is logged separately, not nested here) and address that root cause.","Ensure consumer operations are only invoked from a single, owned thread and that no external code calls Thread.interrupt() on the network thread.","If running under a container/executor with tight thread limits, raise the thread ceiling so the network thread can actually start.","Wrap consumer usage in try-with-resources and on this exception discard the instance and rebuild it with backoff."],"exampleFix":"// before\nKafkaConsumer<String,String> c = new KafkaConsumer<>(props);\nc.subscribe(singleton(\"t\"));\nc.close();\nc.poll(Duration.ZERO); // -> KafkaException: background thread not running\n\n// after\ntry (KafkaConsumer<String,String> c = new KafkaConsumer<>(props)) {\n    c.subscribe(singleton(\"t\"));\n    c.poll(Duration.ofMillis(500));\n}\n// if a poll ever throws this, build a NEW consumer instance rather than retrying on the dead one.","handlingStrategy":"try-catch","validationCode":"// No reliable public API exposes background-thread liveness (the check is\n// inherently racy by design, see ApplicationEventHandler.ensureNetworkThreadAlive).\n// Defensive option: track the consumer lifecycle in your own code so you never\n// call poll/commit after close().\nprivate volatile boolean consumerClosed = false;\n\npublic void safePoll(KafkaConsumer<String,String> c, Duration timeout) {\n    if (consumerClosed || c == null) return;\n    c.poll(timeout);\n}\n\n@Override public void close() { consumerClosed = true; /* close consumer */ }","typeGuard":null,"tryCatchPattern":"// The background (network) thread died or the consumer was closed. Treat as\n// fatal for THIS consumer instance: catch, close, and rebuild a new consumer.\ntry {\n    consumer.poll(Duration.ofMillis(500));\n} catch (org.apache.kafka.common.KafkaException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\n            \"The consumer background thread is not running\")) {\n        log.error(\"Consumer network thread died, recreating consumer\", e);\n        closeQuietly(consumer);\n        consumer = buildConsumer();   // fresh KafkaConsumer with same props\n    } else {\n        throw e;\n    }\n}","preventionTips":["Never reuse a KafkaConsumer after calling close() or after a thread-uncaught error; always create a fresh instance.","Keep the consumer on a single thread; do not share one KafkaConsumer across threads (the background thread check is per-instance).","Register an uncaught-exception handler on your consumer thread so background-thread death is surfaced before the next API call.","Wrap every consumer API call (poll, commitSync, seek, ...) so a dead background thread recreates the consumer instead of leaking."],"tags":["consumer","async-consumer","threads","lifecycle","network-thread"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}