{"record":{"id":"b842cde5a1265cb8","repo":"apache/seatunnel","slug":"bigtablesourcesplitenumerator-closed-during-client","errorCode":null,"errorMessage":"BigtableSourceSplitEnumerator closed during client creation","messagePattern":"BigtableSourceSplitEnumerator closed during client creation","errorType":"exception","errorClass":"EnumeratorClosedException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-google-bigtable/src/main/java/org/apache/seatunnel/connectors/seatunnel/bigtable/source/BigtableSourceSplitEnumerator.java","lineNumber":431,"sourceCode":"     *\n     * @throws EnumeratorClosedException if the enumerator is already closed (or closes during\n     *     construction), so callers can distinguish shutdown from a real sampleRowKeys failure\n     */\n    private BigtableClient getBigtableClient() {\n        synchronized (stateLock) {\n            if (bigtableClient != null) {\n                return bigtableClient;\n            }\n            if (closed) {\n                throw new EnumeratorClosedException(\n                        \"BigtableSourceSplitEnumerator already closed; cannot create client\");\n            }\n        }\n        BigtableClient created = BigtableClient.createInstance(parameters);\n        synchronized (stateLock) {\n            if (closed) {\n                created.close();\n                throw new EnumeratorClosedException(\n                        \"BigtableSourceSplitEnumerator closed during client creation\");\n            }\n            if (bigtableClient == null) {\n                bigtableClient = created;\n                return created;\n            }\n            created.close();\n            return bigtableClient;\n        }\n    }\n\n    /**\n     * Thrown when discovery/client creation observes that {@link #close()} has already run. Not a\n     * Bigtable API failure — callers must not treat it as {@code sampleRowKeys} failure.\n     */\n    static final class EnumeratorClosedException extends IllegalStateException {\n        private static final long serialVersionUID = 1L;\n","sourceCodeStart":413,"sourceCodeEnd":449,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-google-bigtable/src/main/java/org/apache/seatunnel/connectors/seatunnel/bigtable/source/BigtableSourceSplitEnumerator.java#L413-L449","documentation":"After BigtableClient.createInstance() returns, getBigtableClient() re-checks the closed flag and, if the enumerator closed while the client was being created, immediately closes the freshly created client and throws EnumeratorClosedException. This is the second half of the close-race guard: it ensures no orphaned gRPC client survives a shutdown.","triggerScenarios":"BigtableClient.createInstance(parameters) takes long enough (network latency, auth) that enumerator close() completes during creation; the post-creation closed check then fires on the next buildSplits() call.","commonSituations":"Job cancellation concurrent with the very first split enumeration (client creation is slow due to credentials/network issues); environment with slow metadata service delaying createInstance.","solutions":["Re-run the job; the race is transient and the new enumerator builds a fresh client.","If frequent, investigate why close happens during startup (early job failure elsewhere) and fix the root cause.","Pre-warm/validate Bigtable connectivity and credentials before job submission to shorten the creation window."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  splits = enumerator.buildSplits(ctx);\n} catch (EnumeratorClosedException e) {\n  log.warn(\"Enumerator closed while creating BigtableClient; safe to ignore on shutdown: {}\", e.getMessage());\n}","preventionTips":["Validate Bigtable credentials/network before submission to speed up client creation.","Investigate any early job failure that triggers close during startup.","Treat this exception during shutdown as benign; retry only if it occurs mid-run."],"tags":["bigtable","source","lifecycle","race-condition"],"backgroundTag":"invalid-state-transition","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}