{"id":"aa006b4f539e16e3","repo":"apache/kafka","slug":"transactionalid-transactionalid-was-not-includ-aa006b","errorCode":null,"errorMessage":"TransactionalId `{transactionalId}` was not included in the request","messagePattern":"TransactionalId `(.+?)` was not included in the request","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"clients/src/main/java/org/apache/kafka/clients/admin/FenceProducersResult.java","lineNumber":77,"sourceCode":"    /**\n     * Returns a future that provides the epoch ID generated while initializing the given transaction when the request completes.\n     */\n    public KafkaFuture<Short> epochId(String transactionalId) {\n        return findAndApply(transactionalId, p -> p.epoch);\n    }\n\n    /**\n     * Return a future which succeeds only if all the producer fencings succeed.\n     */\n    public KafkaFuture<Void> all() {\n        return KafkaFuture.allOf(futures.values().toArray(new KafkaFuture<?>[0]));\n    }\n\n    private <T> KafkaFuture<T> findAndApply(String transactionalId, KafkaFuture.BaseFunction<ProducerIdAndEpoch, T> followup) {\n        CoordinatorKey key = CoordinatorKey.byTransactionalId(transactionalId);\n        KafkaFuture<ProducerIdAndEpoch> future = futures.get(key);\n        if (future == null) {\n            throw new IllegalArgumentException(\"TransactionalId \" +\n                \"`\" + transactionalId + \"` was not included in the request\");\n        }\n        return future.thenApply(followup);\n    }\n}\n","sourceCodeStart":59,"sourceCodeEnd":83,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/admin/FenceProducersResult.java#L59-L83","documentation":"Thrown by FenceProducersResult.findAndApply (used by producerId/epochId) when the caller asks for the fencing result of a transactionalId that was not part of the original Admin.fenceProducers request. The result resolves IDs to CoordinatorKey; a missing key means the producer was never requested, and lookup fails fast with IllegalArgumentException rather than returning a null future.","triggerScenarios":"Calling result.producerId(txnId) or result.epochId(txnId) where txnId was not in the Collection<String> passed to Admin.fenceProducers. CoordinatorKey.byTransactionalId produces a key not present in the futures map, so future == null triggers the exception.","commonSituations":"Caller fences a subset of producers but queries a different one (typo, stale config, env mismatch); dynamic transactional ID generation for lookup vs static request set; cross-thread sharing of a result object; refactored code that changed the fenced producer list without updating queries.","solutions":["Pass the exact transactional ID string that you included in the fenceProducers request.","Iterate the original requested collection rather than constructing new IDs for lookup.","Use fencedProducers() to get the full map of transactional ID to future instead of querying individual IDs.","If the ID set changed, issue a new fenceProducers call with the complete list."],"exampleFix":"// before\nCollection<String> req = List.of(\"tx-1\");\nFenceProducersResult r = admin.fenceProducers(req);\nr.producerId(\"tx-2\").get(); // not in request\n\n// after\nfor (String id : req) {\n    r.producerId(id).get();\n}\n// or use the bulk accessor\nMap<String, KafkaFuture<Void>> all = r.fencedProducers();","handlingStrategy":"validation","validationCode":"// Keep the collection of transactional IDs sent to fenceProducers and only call\n// producerId(...)/epochId(...) for those.\nCollection<String> requestedIds = List.of(\"tx-1\", \"tx-2\");\nFenceProducersResult result = admin.fenceProducers(requestedIds);\n\nString txId = \"tx-1\";\nif (requestedIds.contains(txId)) {\n    long pid = result.producerId(txId).get();\n} else {\n    log.warn(\"{} not in fenceProducers request\", txId);\n}","typeGuard":null,"tryCatchPattern":"try {\n    long pid = result.producerId(txId).get();\n} catch (IllegalArgumentException e) {\n    // `txId` was not in the fenceProducers request. Resubmit or drop.\n    log.warn(\"Cannot fence {}: {}\", txId, e.getMessage());\n}","preventionTips":["Drive producerId(...)/epochId(...) calls from the same collection passed to Admin.fenceProducers.","Use result.all() or result.fencedProducers() for bulk consumption; they never throw the not-included error.","Normalize transactional IDs before the request and the lookup so duplicates/typos do not cause a miss.","Issue a fresh fenceProducers call when the set of IDs changes, rather than reusing a stale result."],"tags":["admin-client","producer-fencing","transactions","api-misuse","illegal-argument","request-set"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}