apache/seatunnel · error · EnumeratorClosedException

BigtableSourceSplitEnumerator closed during client creation

Error message

BigtableSourceSplitEnumerator closed during client creation

What it means

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.

Source

Thrown at seatunnel-connectors-v2/connector-google-bigtable/src/main/java/org/apache/seatunnel/connectors/seatunnel/bigtable/source/BigtableSourceSplitEnumerator.java:431

     *
     * @throws EnumeratorClosedException if the enumerator is already closed (or closes during
     *     construction), so callers can distinguish shutdown from a real sampleRowKeys failure
     */
    private BigtableClient getBigtableClient() {
        synchronized (stateLock) {
            if (bigtableClient != null) {
                return bigtableClient;
            }
            if (closed) {
                throw new EnumeratorClosedException(
                        "BigtableSourceSplitEnumerator already closed; cannot create client");
            }
        }
        BigtableClient created = BigtableClient.createInstance(parameters);
        synchronized (stateLock) {
            if (closed) {
                created.close();
                throw new EnumeratorClosedException(
                        "BigtableSourceSplitEnumerator closed during client creation");
            }
            if (bigtableClient == null) {
                bigtableClient = created;
                return created;
            }
            created.close();
            return bigtableClient;
        }
    }

    /**
     * Thrown when discovery/client creation observes that {@link #close()} has already run. Not a
     * Bigtable API failure — callers must not treat it as {@code sampleRowKeys} failure.
     */
    static final class EnumeratorClosedException extends IllegalStateException {
        private static final long serialVersionUID = 1L;

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Re-run the job; the race is transient and the new enumerator builds a fresh client.
  2. If frequent, investigate why close happens during startup (early job failure elsewhere) and fix the root cause.
  3. Pre-warm/validate Bigtable connectivity and credentials before job submission to shorten the creation window.
Defensive patterns

Strategy: retry

Try / catch

try {
  splits = enumerator.buildSplits(ctx);
} catch (EnumeratorClosedException e) {
  log.warn("Enumerator closed while creating BigtableClient; safe to ignore on shutdown: {}", e.getMessage());
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/b842cde5a1265cb8. Report an issue: GitHub.