• Type: Bug
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Query Execution
    • ALL
    • v9.0
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      Problem

      A document whose BSON size is exactly BSONObjMaxUserSize (16777216 bytes) is a legal stored document, but it cannot be materialized as a Value of type BinData, because RCString::create() uses a strict < against BSONObjMaxUserSize:

      // src/mongo/db/exec/document_value/value_internal.h:36
      static constexpr size_t sizeLimit = BSONObjMaxUserSize;
      uassert(ErrorCodes::BSONObjectTooLarge,
              fmt::format("RCString too large. Requires size={} < limit={}", s.size(), sizeLimit),
              s.size() < sizeLimit);
      

      BinData values are stored through this path (value_internal.h:283), so {{$convert:

      {input: "$$ROOT", to: "binData"}

      }} on a maximally-sized document fails with:

      (BSONObjectTooLarge) Executor error during find command: test.find_getmore_bsonsize :: caused by ::
      RCString too large. Requires size=16777216 < limit=16777216
      

      The two boundary conventions disagree: documents are valid at BSONObjMaxUserSize (inclusive), while RCString permits only sizes strictly below it. Anything at exactly the max is rejected.

      Note the error text reads like a requirement that should have been satisfied — it prints the observed size and the limit into a "size={} < limit=" template, so an at-the-boundary failure looks like an off-by-one in the message even though the predicate is behaving as written. The wording is worth fixing along with the limit.

      How it was hit

      Reported by mongosync's initial-sync hash check, which projects every document through:

      { hash: { $hash: { algorithm: "xxh64",
                         input: { $convert: { input: "$$ROOT", to: "binData" } } } } }
      

      Only the 8-byte hash is returned to the client, so there is no risk of an oversized reply — the value simply cannot be constructed. This makes a collection containing a max-size document unhashable, and the error is non-retryable, so the migration fails outright.

      Steps to Reproduce

      db.c.insertOne(/* a document whose BSON size is exactly 16777216 bytes */);
      db.c.find({}, { _id: 0,
                      hash: { $hash: { algorithm: "xxh64",
                                       input: { $convert: { input: "$$ROOT", to: "binData" } } } } });
      

      Expected Behavior

      • Any document the server accepted on write can be converted to binData and hashed.
      • BSONObjMaxUserSize works as an inclusive limit, consistent with how document validity is defined elsewhere.

      Actual Behavior

      • BSONObjectTooLarge / RCString too large for a document at exactly the max size.

      Scope of Work

      • src/mongo/db/exec/document_value/value_internal.h — allow sizes up to and including BSONObjMaxUserSize (or the appropriate internal max for values that are never round-tripped into a reply), and reword the assertion message so it does not read as an off-by-one.
      • Add a unit test covering a string/BinData of exactly BSONObjMaxUserSize.

      Related

      • SERVER-112267 — previous cleanup of this same assertion (error code).

            Assignee:
            Unassigned
            Reporter:
            Felipe Gasper
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: