-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: 9.0.2, 8.0.33
-
Component/s: None
-
None
-
DB Integration & Observability
-
ALL
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Overview
A whole-cluster change stream ($changeStream: {allChangesForCluster: true}) always runs its aggregate/getMore commands against the admin database. Any querySettings passed inline on that command (query knob overrides, maxTimeMS, index hints, reject) is silently dropped instead of being applied, regardless of topology (replica set, sharded cluster via mongos, or a direct connection to a shard).
Root Cause
QuerySettingsService::isEligbleForQuerySettings() in src/mongo/db/query/query_settings/query_settings_service.cpp rejects any namespace where nss.isOnInternalDb() is true:
// Query settings can not be set on internal dbs or system collections in user dbs. >if (nss.isOnInternalDb() || nss.isSystem()) { return false; }
isOnInternalDb() returns true for the admin database (isAdminDB() || isLocalDB() || isConfigDB()). Since a whole-cluster change stream's command namespace is admin.$cmd.aggregate, lookupQuerySettingsWithRejectionCheck() always short-circuits via the !isEligbleForQuerySettings(expCtx, nss) check in query_settings_service.h and returns default QuerySettings(), discarding querySettingsFromOriginalCommand entirely. This check exists to exclude genuinely internal/system namespaces (e.g. admin.system.keys, config.*) from query settings, but it also incidentally catches the admin namespace used by cluster-wide change streams, which is a legitimate user-facing query shape.
This reproduces on a bare mongod/replica set with no router involved at all \u2014 it is not specific to any particular topology or to bypassing mongos.
Evidence
Reproduced via jstests/change_streams/change_stream_response_deadline.js ("using query settings override" cases), which opens an allChangesForCluster stream with an inline querySettings.queryKnobs.operationResponseMaxMS override. The knob had no effect: a single getMore ran an entire uninterrupted collection scan instead of yielding on the configured deadline. Added a temporary debug log inside isEligbleForQuerySettings() and confirmed it fires and returns false for nss: "admin.$cmd.aggregate", at exactly the point the test's aggregate/getMore commands are processed:
"msg":"isEligbleForQuerySettings rejecting internal/system namespace","attr":\{"nss":"admin.$cmd.aggregate"\}
Impact
Any client opening a whole-cluster change stream that relies on inline querySettings will have those settings silently ignored, with no error surfaced to the caller. This affects the feature on every topology, not just direct-to-shard connections.
Suggested Fix
Distinguish "admin db because it's a whole-cluster change stream" from "admin db because it's a genuinely internal/system namespace" in isEligbleForQuerySettings(), so that cluster-wide change streams remain eligible for querySettings.
Repro
- Test: jstests/change_streams/change_stream_response_deadline.js ("using query settings override" cases)
- Also reproducible directly against a bare mongod/replica set with an allChangesForCluster stream + inline querySettings; no sharding or router involvement required.