apache/beam · warning

RCSP : CloseStream has tokens that don't cover the entire…

Error message

RCSP {}: CloseStream has tokens {} that don't cover the entire keyspace

What it means

ReadChangeStreamPartitionAction logs 'RCSP {}: CloseStream has tokens {} that don't cover the entire keyspace' when handling a CloseStream response: the flow tokens returned by the server, converted to partitions, do not cover the same range as the partition being closed. The connector logs the warning and proceeds with cleanup anyway.

Solutions

  1. Usually no action needed — the connector still performs cleanup and children are processed normally.
  2. If it recurs and data gaps appear, verify child partition registration in the metadata table.
  3. Ensure the change stream was not recreated/resized mid-run; avoid altering table splits aggressively while streaming.
  4. Upgrade the connector for improved split/merge token handling.
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: During a partition split or merge, the CloseStream response's tokens (tokenPartitions) differ from partitionRecord's full ByteStringRange, failing coverSameKeySpace(tokenPartitions, partition).

Common situations: Bigtable automatically split or merged partitions concurrently with the stream close; server-side token truncation; transient inconsistency during rebalancing.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/3ae2f2647cdae1bf. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/changestreams/action/ReadChangeStreamPartitionAction.java:259

        } else {
          childPartition = closeStream.getChangeStreamContinuationTokens().get(i).getPartition();
        }
        childPartitions.add(childPartition);
        ChangeStreamContinuationToken token =
            getTokenWithCorrectPartition(
                partitionRecord.getPartition(),
                closeStream.getChangeStreamContinuationTokens().get(i));
        tokenPartitions.add(token.getPartition());
        metadataTableDao.writeNewPartition(
            new NewPartition(
                childPartition, Collections.singletonList(token), watermarkEstimator.getState()));
      }
      LOG.info(
          "RCSP {}: Split/Merge into {}",
          formatByteStringRange(partitionRecord.getPartition()),
          partitionsToString(childPartitions));
      if (!coverSameKeySpace(tokenPartitions, partitionRecord.getPartition())) {
        LOG.warn(
            "RCSP {}: CloseStream has tokens {} that don't cover the entire keyspace",
            formatByteStringRange(partitionRecord.getPartition()),
            partitionsToString(tokenPartitions));
      }
      // Perform the real cleanup. This step is no op if the race mentioned above occurs (splits and
      // merges results back to this partition again) because when we register the "new" partition,
      // we unset the deletion bit.
      metadataTableDao.deleteStreamPartitionRow(partitionRecord.getPartition());
      return ProcessContinuation.stop();
    }

    // Update the metadata table with the watermark
    metadataTableDao.updateWatermark(
        partitionRecord.getPartition(),
        watermarkEstimator.getState(),
        tracker.currentRestriction().getCurrentToken());

    // Start to stream the partition.

View on GitHub (pinned to 12126d8942)