{"id":"ba1bc09fa6d3be35","repo":"apache/kafka","slug":"all-records-must-be-acknowledged-in-explicit-ackno","errorCode":null,"errorMessage":"All records must be acknowledged in explicit acknowledgement mode.","messagePattern":"All records must be acknowledged in explicit acknowledgement mode\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/ShareConsumerImpl.java","lineNumber":1218,"sourceCode":"\n    /**\n     * If the acknowledgement mode is IMPLICIT, acknowledges all records in the current batch.\n     */\n    private void acknowledgeBatchIfImplicitAcknowledgement() {\n        // If IMPLICIT, acknowledge all records\n        if (acknowledgementMode == ShareAcknowledgementMode.IMPLICIT) {\n            currentFetch.acknowledgeAll(AcknowledgeType.ACCEPT);\n        }\n    }\n\n    /**\n     * If the acknowledgement mode is EXPLICIT, ensure that all in-flight records have been acknowledged.\n     */\n    private void ensureInFlightAcknowledgedIfExplicitAcknowledgement() {\n        if (acknowledgementMode == ShareAcknowledgementMode.EXPLICIT) {\n            if (!currentFetch.checkAllInFlightAreAcknowledged()) {\n                // We cannot leave unacknowledged records in EXPLICIT acknowledgement mode, so we throw an exception to the application.\n                throw new IllegalStateException(\"All records must be acknowledged in explicit acknowledgement mode.\");\n            }\n        }\n    }\n\n    /**\n     * Returns any ready acknowledgements to be sent to the cluster.\n     */\n    private Map<TopicIdPartition, NodeAcknowledgements> acknowledgementsToSend() {\n        return currentFetch.takeAcknowledgedRecords();\n    }\n\n    /**\n     * Called to verify if the acknowledgement mode is EXPLICIT, else throws an exception.\n     */\n    private void ensureExplicitAcknowledgement() {\n        if (acknowledgementMode == ShareAcknowledgementMode.IMPLICIT) {\n            throw new IllegalStateException(\"Implicit acknowledgement of delivery is being used.\");\n        }","sourceCodeStart":1200,"sourceCodeEnd":1236,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/ShareConsumerImpl.java#L1200-L1236","documentation":"Thrown by ensureInFlightAcknowledgedIfExplicitAcknowledgement() (line 1218) at the start of poll() when the acknowledgement mode is EXPLICIT and currentFetch.checkAllInFlightAreAcknowledged() returns false. In explicit mode every record fetched in the previous batch must be acknowledged (ACCEPT/REJECT/RELEASE) before the next poll, otherwise the client refuses to fetch more records and surfaces the gap as an IllegalStateException.","triggerScenarios":"Calling consumer.poll(...) in explicit acknowledgement mode without having called consumer.acknowledge(...) on every record returned by the previous poll(). Also triggered when acknowledgements are partial (only some records of a batch were acknowledged) or when an earlier acknowledge() call targeted a record not in the current fetch.","commonSituations":"Application filters records and skips acknowledge() for the filtered-out ones; exception in the processing loop that bypasses the finally-block acknowledge; partial batch retries where only failing records are re-acked; migrating from implicit mode without updating the processing loop to ack every record.","solutions":["In explicit mode, acknowledge every record returned by each poll() — wrap processing in try/finally and call acknowledge() for each ConsumerRecord.","If you cannot ack per-record, switch the consumer to implicit acknowledgement mode by setting share.acknowledgement.mode=implicit, which auto-acks the whole batch.","Use consumer.acknowledgeAll(AcknowledgeType.ACCEPT) (if exposed via your API surface) to ack the remaining records before the next poll when you truly mean to accept all.","Audit the processing pipeline for early returns/continues/exceptions that skip the acknowledge call."],"exampleFix":"// before\nfor (ConsumerRecord<String,String> r : records) {\n    if (r.value() == null) continue; // never acknowledged -> next poll throws\n    process(r);\n    consumer.acknowledge(r);\n}\n\n// after\nfor (ConsumerRecord<String,String> r : records) {\n    try {\n        process(r);\n        consumer.acknowledge(r, AcknowledgeType.ACCEPT);\n    } catch (Exception e) {\n        consumer.acknowledge(r, AcknowledgeType.REJECT);\n    }\n}","handlingStrategy":"validation","validationCode":"// In EXPLICIT acknowledgement mode, ensure every in-flight record is acknowledged before the next poll().\n// Track unacked records locally so the precondition is never violated.\njava.util.Set<org.apache.kafka.clients.consumer.ShareRecord> inFlight =\n    java.util.Collections.newSetFromMap(new java.util.concurrent.ConcurrentHashMap<>());\n\nfor (org.apache.kafka.clients.consumer.ShareRecord<K,V> r : records) {\n    inFlight.add(r);\n    // ... process ...\n    consumer.acknowledge(r, org.apache.kafka.clients.consumer.AcknowledgeType.ACCEPT);\n    inFlight.remove(r);\n}\nif (!inFlight.isEmpty()) {\n    throw new IllegalStateException(\"Cannot poll: \" + inFlight.size() + \" records still unacknowledged\");\n}\nconsumer.poll(java.time.Duration.ofMillis(100));","typeGuard":"null","tryCatchPattern":"try {\n    consumer.poll(java.time.Duration.ofMillis(100));\n} catch (IllegalStateException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"must be acknowledged\")) {\n        // drain unacked records (acknowledge them) before retrying the poll\n        drainAndAcknowledgeInFlight(consumer);\n    } else {\n        throw e;\n    }\n}","preventionTips":["In explicit mode, acknowledge each ShareRecord (or use acknowledgeAll on the batch) before the next poll.","Switch to implicit acknowledgement mode if you do not need per-record ack semantics.","Track unacked records in a local set and assert it is empty before each poll to catch the error early."],"tags":["share-consumer","acknowledgement","explicit-mode","poll"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}