ExportXMLWordPrintableJSON

    • Catalog and Routing
    • Fully Compatible
    • ALL
    • v9.0, v8.3, v8.0, v7.0
    • Hide

      Provided in the description.

      Show
      Provided in the description.
    • CAR Team 2026-08-03
    • 200
    • 🟥 DDL
    • None
    • None
    • None
    • None
    • None
    • None

      Issue Status as of Oct 15, 2026

      ISSUE DESCRIPTION AND IMPACT

      In sharded clusters, renaming a collection to a different database (a cross-database rename) can result in permanent loss of the source collection's data — with no error returned to the calling application. This happens if the target namespace does not already exist prior to the rename, and the operation is interrupted (for example, by a primary step-down) at one specific point during execution.

      Concretely: a coordinator process carries out a cross-database rename by cloning the source collection's data to the destination, then dropping the source. If an interruption lands strictly after the source collection is dropped but before that step is checkpointed, the coordinator's retry logic incorrectly treats the already-renamed destination as leftover state and drops it too. The result is that both the source and destination collections are lost. Critically, the renameCollection command itself reports success to the caller even when this occurs, so there is no error an application can catch.

      This does not affect same-database renames, renames onto an already-existing destination, or sharded source collections.

      DIAGNOSIS AND AFFECTED VERSIONS

      Affected: all MongoDB versions from 5.0 onward — this is when cross-database rename support was added to sharded clusters.

      Fixed in:

      • 9.0.0+
      • 8.3.13+
      • 8.0.34+
      • 7.0.45+

      You are impacted only if all of the following are true:

      • Your deployment is a sharded cluster.
      • You perform a renameCollection where the source and target namespaces belong to different databases.
      • The target namespace does not already exist prior to the rename.
      • The source collection is unsharded.
      • The operation is interrupted at one specific point within a narrow window: after the source collection's data has been copied to the destination and the source collection is dropped, but before that step is checkpointed (for example, by a primary step-down).

      You are not impacted if any of the following hold:

      • You do not run a sharded cluster.
      • You only perform same-database renames.
      • Your rename's target namespace already existed before the operation.
      • Your source collection is sharded.

      There is no proactive way to check whether this has already happened. The clearest indication is an application noticing that an expected collection is unexpectedly missing or empty following a cross-database rename.

      REMEDIATION AND WORKAROUNDS

      Upgrade to 9.0.0, 8.3.13, 8.0.34, or 7.0.45 (or later within your series). Upgrading prevents the bug from recurring going forward, but does not recover any data already lost.

      Until upgraded, avoid cross-database renameCollection operations onto a destination namespace that does not already exist, particularly around events likely to trigger a primary step-down (planned maintenance, rolling upgrades, manual failover testing). As an alternative, create the destination namespace before initiating the rename and run the operation with dropTarget: true.

      If data has already been lost, the only path to recovery is restoring the source collection from a pre-incident backup or snapshot.

      —-----------------------------------------------------

       

      Original description
      Problem

      A cross-database renameCollection can lose the renamed collection if the primary node of the data-bearing participant shard's replica set steps down after the target has been created and the source dropped, but before the participant restores its range-deletion state and advances beyond kRenameLocalAndRestoreRangeDeletions.

      After recovery:

      • The source is absent because it was already dropped.
      • The target exists with the fresh UUID assigned to the cross-database rename.
      • The recovered participant re-executes kRenameLocalAndRestoreRangeDeletions.

      The recovered phase invokes renameOrDropTarget(): participant phase invocation.

      renameOrDropTarget() only recognizes a completed rename when the target UUID equals the original source UUID: participant idempotency check.

      That check works for same-database renames, but cross-database renames deliberately assign a fresh target UUID: cross-database target UUID creation.

      Although newTargetCollectionUuid is forwarded into the participant phase, it is not considered by the idempotency check. renameOrDropTarget() therefore invokes validateAndRunRenameCollection().

      The underlying cross-database rename returns NamespaceNotFound because the source is absent, and uassertStatusOK() converts that status into an exception: missing-source path and validateAndRunRenameCollection.

      Control returns to the NamespaceNotFound catch block in renameOrDropTarget(), which invokes dropCollectionLocally() on the successfully renamed target: target drop.

      Observed sequence
      1. An untracked collection is renamed across databases.
      2. The participant creates the target with a fresh UUID.
      3. The temporary collection is renamed to the target and the source is dropped.
      4. A shard stepdown interrupts the participant while restoring range-deletion state.
      5. The new primary recovers and repeats the local rename phase.
      6. The source is absent and the target UUID differs from the source UUID.
      7. The participant handles NamespaceNotFound by dropping the successfully renamed target.
      8. The coordinator completes, leaving both source and target absent.
      Expected behavior

      A recovered participant must recognize that the rename has already completed when the target UUID matches newTargetCollectionUuid. The target collection and its documents must remain intact.

      Actual behavior

      The recovered participant drops the target collection. Since the source was already dropped, both namespaces are absent after the operation, presenting a data-loss risk.

      Deterministic reproducer

      A focused C++ reproducer has been pushed:

      The test directly models the recovered state:

      • Source namespace is absent.
      • Target exists with a document and a fresh UUID.
      • newTargetCollectionUuid matches the target UUID.
      • The original source UUID is different.
      • Re-running the participant unexpectedly drops the target.

      Run with:

      bazel run +rename_collection_participant_service_test 

      The test currently fails with:

      FAIL: Value of: targetUUIDAfterRetry
        Actual: false
      Expected: true
      The recovered participant dropped the already-renamed cross-database target
      
      Acceptance criteria
      • Participant retries recognize a completed cross-database rename using newTargetCollectionUuid.
      • A missing source does not cause the successfully renamed target to be dropped.
      • The target UUID and documents are preserved.
      • The deterministic reproducer passes.
      • Same-database rename and legitimate non-data-bearing participant behavior remain unchanged.

            Assignee:
            Vishesh Ruparelia
            Reporter:
            Vishesh Ruparelia
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: