Fix handling of user $-prefixed fields colliding with internal metadata

XMLWordPrintableJSON

    • Type: Task
    • Resolution: Fixed
    • Priority: Major - P3
    • 9.0.0-rc0, 8.3.3, 8.2.10, 8.0.24, 7.0.35
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Execution
    • Fully Compatible
    • v8.3, v8.2, v8.0, v7.0
    • QE 2026-04-27
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      `DocumentStorage::loadLazyMetadata()` unconditionally consumes `$`-prefixed BSON fields matching internal metadata names (e.g. `$textScore`, `$pt`, `$changeStreamControlEvent`) even when the BSON comes from user data (via `$literal`, `$setField`, etc.). This causes silent metadata corruption, type-mismatch errors, and occasional crashes — most visibly on cross-shard aggregations where the merge step serializes user fields alongside real metadata.

      The fix ships in three commits:

      1. #51366 — Guard `loadLazyMetadata()`

      Add a `_bsonHasMetadata` guard so user-supplied `$`-prefixed fields are not reinterpreted as metadata on single-shard documents. Matches the existing check in the document field iterator (`shouldSkipDeleted()`).

      1. #51679 — Strip collisions during cross-shard merge

      Introduce `Document::toBsonStrippingMetadata()` so the cross-shard merge serialization strips metadata-colliding user fields before appending real metadata. Also adds a `DocumentStorage::findField` guard that hides metadata-named fields from the document lookup API, so they are only accessible through the metadata API.

      1. #52144 — Warn when stripping

      Log a rate-limited (one per second, via `logv2::SeveritySuppressor`) WARNING when (2) strips a field, so operators have visibility into fields being dropped. The field name is wrapped in `redact()`, so it shows as `###` in deployments running with `--redactClientLogData`.

            Assignee:
            Catalin Sumanaru
            Reporter:
            Catalin Sumanaru
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: