apache/beam · warning
RCSP : Subsequent run that doesn't hold the lock . This is…
Error message
RCSP {} : Subsequent run that doesn't hold the lock {}. This is not unexpected and should probably be reviewed. What it means
ReadChangeStreamPartitionAction.run logs 'RCSP <partition>: Subsequent run that doesn't hold the lock <uuid>' when a retried attempt of the same partition/uuid does not pass the lock verification, meaning this worker is processing a partition whose lock it does not (or no longer) hold. The connector marks streamProgress.setFailToLock(true) so the partition is re-assigned.
Solutions
- Usually safe to ignore: the connector fails the lock and the partition will be retried/assigned correctly.
- If it repeats persistently, check for multiple pipeline instances streaming the same change stream concurrently.
- Verify the app profile allows multi-row transactions and that the metadata table is healthy.
- Report/upgrade if the lock check consistently fails despite a single runner (known review-needed warning per the message).
Example fix
// before // two streaming jobs reading the same change stream -> lock contention // after // stop the duplicate job; keep exactly one ReadChangeStream pipeline per stream
Defensive patterns
Strategy: retry
Try / catch
try { partitionAction.run(record, receiver); } catch (RuntimeException e) { /* runner retries; connector sets failToLock and reassigns the partition */ } Prevention
- Ensure only one job consumes each change stream.
- Use an app profile that allows safe retries (single-row transactions).
- Investigate persistent occurrences — they indicate duplicated consumers or lock-state bugs.
When it happens
Trigger: A bundle retry of ReadChangeStreamPartitionAction for the same PartitionRecord uuid after the lock was released/cleaned up (e.g. a retry of CloseStream), or the restriction tracker/lock state changed between attempts.
Common situations: Runner-level bundle retries after transient failures; work stealing/reassignment where another worker already processed the partition; race during CloseStream cleanup.
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
- DNP: New partition does not have all the parents
- DNP: Reconciling missing partition
- DNP: Updating watermark failed due to missing
- DNP: Updating watermark failed due to overlapping
- RCSP : CloseStream has tokens that don't cover the entire…
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/f985288440ee5e91.
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:172
"RCSP {} : Could not acquire lock with uid: {}, because this is a "
+ "duplicate and another worker is working on this partition already.",
formatByteStringRange(partitionRecord.getPartition()),
partitionRecord.getUuid());
StreamProgress streamProgress = new StreamProgress();
streamProgress.setFailToLock(true);
metrics.decPartitionStreamCount();
tracker.tryClaim(streamProgress);
return ProcessContinuation.stop();
}
} else if (tracker.currentRestriction().getCloseStream() == null
&& !metadataTableDao.doHoldLock(
partitionRecord.getPartition(), partitionRecord.getUuid())) {
// We only verify the lock if we are not holding CloseStream because if this is a retry of
// CloseStream we might have already cleaned up the lock in a previous attempt.
// Failed correctness check on this worker holds the lock on this partition. This shouldn't
// fail because there's a restriction tracker which means this worker has already acquired the
// lock and once it has acquired the lock it shouldn't fail the lock check.
LOG.warn(
"RCSP {} : Subsequent run that doesn't hold the lock {}. This is not unexpected and "
+ "should probably be reviewed.",
formatByteStringRange(partitionRecord.getPartition()),
partitionRecord.getUuid());
StreamProgress streamProgress = new StreamProgress();
streamProgress.setFailToLock(true);
metrics.decPartitionStreamCount();
tracker.tryClaim(streamProgress);
return ProcessContinuation.stop();
}
// Process CloseStream if it exists
CloseStream closeStream = tracker.currentRestriction().getCloseStream();
if (closeStream != null) {
LOG.debug("RCSP: Processing CloseStream");
metrics.decPartitionStreamCount();
if (closeStream.getStatus().getCode() == Status.Code.OK) {
// We need to update watermark here. We're terminating this stream because we have reachedView on GitHub (pinned to 12126d8942)