MongoDB 6 vs 7 Schema Validation Changes
Teams planning a MongoDB 6.x to 7.x upgrade often ask which of their $jsonSchema validators need rewriting before cutover, and the measured answer this page gives is: none. It sits under Understanding MongoDB $jsonSchema Syntax within the broader MongoDB JSON Schema Validation Architecture, and its purpose is to separate what genuinely changed for validation authors across these two releases from what stayed byte-for-byte identical, so you can plan an upgrade with evidence rather than superstition. The short version is that $jsonSchema continues to implement JSON Schema Draft 4 semantics in both major versions, the structured failure detail that landed in 5.0 persists unchanged through 6 and 7, and validator syntax you author on 6.x deploys and behaves identically on 7.x. The reader outcome is a repeatable way to prove that portability on a throwaway collection before you touch a production replica set.
Operational Mechanics and Write-Path Impact
The validation subsystem did not fork between MongoDB 6.0 and 7.0. A $jsonSchema document is still compiled into a query predicate evaluated synchronously on the write path — insert, update, replace, findAndModify — with $out and $merge bypassing it on the destination exactly as before. The keyword surface is the same Draft 4 subset in both: bsonType, required, enum, pattern, properties, additionalProperties, patternProperties, the allOf/anyOf/oneOf/not combinators, and the numeric and array bounds. Neither release added a $jsonSchema keyword, and neither began honoring the later-draft keywords (if/then/else, $defs, unevaluatedProperties) that both continue to reject at collMod time. A schema that deploys on 6.0 deploys on 7.0, and a schema that fails on 6.0 fails identically on 7.0.
The meaningful usability improvement that authors care about — the structured errInfo.details.schemaRulesNotSatisfied object that names the exact failing keyword and JSON path — is not a 7.0 feature. It arrived in 5.0 and is carried forward unchanged through 6 and 7. If you are upgrading from 4.x, that structured detail is the real jump; if you are moving 6 to 7, it is already present on both sides and produces the same shape.
Because there is no divergence in the validator itself, the entire feature comparison collapses into a table of “same” rows. The value of enumerating them is precisely that it lets you rule out a regression cause during an upgrade incident:
| Validation feature | MongoDB 6.x | MongoDB 7.x |
|---|---|---|
$jsonSchema draft semantics |
Draft 4 | Draft 4 |
Structured errInfo.details.schemaRulesNotSatisfied |
Present (since 5.0) | Present |
validationLevel (strict / moderate / off) |
Supported | Supported |
validationAction (error / warn) |
Supported | Supported |
| Failure code on rejected write | WriteError code 121 |
WriteError code 121 |
Later-draft keywords (if/then, $defs, format) |
Rejected at collMod |
Rejected at collMod |
collMod as metadata-only change |
Yes | Yes |
$out / $merge bypass the validator |
Yes | Yes |
bsonType extension (decimal, objectId, date) |
Supported | Supported |
What actually differs between 6.0 and 7.0 lives outside the validation contract — the query engine, storage internals, time-series enhancements, and the sharding surface all evolved — but none of it changes what your $jsonSchema accepts or rejects. Treat the validator as a stable artifact across the boundary and spend your upgrade budget on the things that did move.
Exact Diagnostic Fingerprints and Fast Resolution
The one upgrade-specific mechanic that does gate behavior is the featureCompatibilityVersion (FCV), and it is easy to misread as a validation problem. Moving a deployment to 7.0 requires the FCV to already be at 6.0; a binary upgrade with a lagging FCV can refuse newer commands. This never affects $jsonSchema evaluation — validators run the same at any FCV — but during a mixed-version window it is the first thing to confirm so you do not chase a phantom validation regression. Read the live server version and FCV directly:
// Ground-truth server version and feature compatibility, per node.
db.version()
// e.g. "7.0.11"
db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })
// => { featureCompatibilityVersion: { version: "7.0" }, ok: 1 }
The signatures below distinguish a real portability issue from noise during a 6 to 7 migration. Note that the first two are version-independent by design — they present identically on both releases, which is itself the diagnostic:
| Signature | Where it appears | Root cause | Resolution |
|---|---|---|---|
code 121, "Document failed validation" |
Driver / client on both 6.x and 7.x | The document genuinely violates the schema | Read errInfo.details.schemaRulesNotSatisfied; the detail is identical across versions |
Unknown $jsonSchema keyword: <name> at collMod |
mongod on both 6.x and 7.x |
Schema uses a later-draft keyword neither version honors | Rewrite with Draft 4 combinators; this is not fixed by upgrading |
OperationFailure code 13 (Unauthorized) on collMod |
Automation principal | Missing collMod privilege, unrelated to version |
Grant dbAdmin; no version dependency |
| Newer command rejected during upgrade | mongod mid-upgrade |
FCV still at 6.0 while binary is 7.0, or vice versa |
Advance FCV in the correct order; does not touch validators |
The takeaway for triage: if a validator behaves differently after an upgrade, the cause is almost never the validation engine. Confirm the two collections carry byte-identical options.validator, validationLevel, and validationAction, and the discrepancy will resolve to configuration drift, not a version regression.
Step-by-Step Playbook
This sequence proves validator portability on a disposable namespace before you rely on it in production. It is safe to run against a 6.x node and a 7.x node — a staging replica of each, or the same throwaway collection observed before and after an in-place upgrade — and it never touches real data. The principle is the idempotent dry-run pattern used across collection-level validators: exercise the schema on a scratch collection, capture the exact rejection, then diff.
1. Create a throwaway collection with the candidate validator on 6.x. Attach the exact schema you run in production so the test is representative:
db.__v67_probe.drop()
db.createCollection("__v67_probe", {
validator: { $jsonSchema: {
bsonType: "object",
required: ["tenant_id", "currency"],
properties: {
tenant_id: { bsonType: "string", minLength: 1 },
currency: { bsonType: "string", pattern: "^[A-Z]{3}$" }
},
additionalProperties: false
}},
validationLevel: "strict",
validationAction: "error"
})
// Expected output: { ok: 1 }
2. Capture the applied options and a known-bad rejection. Record both the stored validator and the structured failure detail — these are the artifacts you will compare after the upgrade:
db.getCollectionInfos({ name: "__v67_probe" })[0].options
// => { validator: {...}, validationLevel: "strict", validationAction: "error" }
try {
db.__v67_probe.insertOne({ tenant_id: "acme", currency: "usd" }) // lowercase fails pattern
} catch (e) {
printjson(e.errInfo.details.schemaRulesNotSatisfied)
// records the exact failing keyword + path, e.g. pattern on "currency"
}
3. Recreate the identical probe on 7.x and replay. After the upgrade (or on the 7.x staging node), repeat steps 1 and 2 verbatim. A driver-side script makes the comparison mechanical rather than visual:
from pymongo import MongoClient
from pymongo.errors import WriteError
client = MongoClient("mongodb://localhost:27017") # point at the 7.x node
db = client.staging
def probe_options_and_failure(schema: dict) -> tuple[dict, list]:
db.drop_collection("__v67_probe")
db.create_collection("__v67_probe", validator={"$jsonSchema": schema},
validationLevel="strict", validationAction="error")
opts = db.command("listCollections", filter={"name": "__v67_probe"}
)["cursor"]["firstBatch"][0]["options"]
try:
db.__v67_probe.insert_one({"tenant_id": "acme", "currency": "usd"})
rules = [] # unexpected: the bad doc was accepted
except WriteError as exc:
rules = exc.details["errInfo"]["details"]["schemaRulesNotSatisfied"]
return opts, rules
4. Diff the two captures. The options objects and the schemaRulesNotSatisfied structures must match between versions. If they do, the validator is proven portable and needs no rewrite:
db.__v67_probe.drop() // clean up the disposable namespace
// Expected: identical options + identical failing-keyword path on 6.x and 7.x
Failure Modes & Rollback
Each step has a bounded, low-risk failure mode because nothing here writes to a production collection:
- The probe schema is rejected on one version but not the other (step 1 or 3). This should never happen for a genuine Draft 4 schema. If it does, the schema contains a later-draft keyword that one path tolerated only because it was never actually deployed — inspect the
collMod/createCollectionerror text forUnknown $jsonSchema keywordand rewrite with combinators. Upgrading does not fix it. optionsdiffer between captures (step 4). The cause is configuration drift, not the engine — a differingvalidationLevelor a stale validator on one node. Reapply the intended validator withcollModso both nodes carry identical metadata.- FCV blocks a command mid-upgrade (step 3). Confirm the FCV with the diagnostic above and advance it in order; this is an upgrade-sequencing issue that is independent of any validator.
There is no data rollback to perform — the probe is a disposable namespace, so recovery is simply db.__v67_probe.drop(), which is instantaneous. For the production collections themselves, the upgrade does not modify validators, so no validator rollback is required; if you separately changed a validator during the maintenance window, revert it with a single metadata-only collMod that restores the prior options, with a time-to-recover of the replication lag of your slowest secondary. Version the schema artifact you deploy through schema versioning strategies for NoSQL so “the validator we ran on 6.x” is a retrievable, auditable object rather than a memory.
Frequently Asked Questions
Do I need to rewrite my $jsonSchema validators when upgrading from MongoDB 6 to 7?
No. Both 6.x and 7.x implement JSON Schema Draft 4 semantics with the same keyword surface, the same validationLevel and validationAction dials, and the same code 121 rejection carrying schemaRulesNotSatisfied. A validator authored and deployed on 6.x behaves identically on 7.x, and the reverse is also true. The disposable-collection probe in the playbook proves this for your specific schema before cutover.
Did MongoDB 7.0 add any new schema validation keywords or change the failure detail?
No new $jsonSchema keywords were added in 7.0, and the later-draft keywords such as if/then/else and $defs are still rejected at collMod time exactly as in 6.x. The structured errInfo.details.schemaRulesNotSatisfied object is unchanged — it was introduced in 5.0 and is carried forward through 6 and 7 with the same shape, so downstream error parsers need no update.
Does featureCompatibilityVersion affect how a validator behaves?
No. FCV gates which server commands and storage features are available during and after an upgrade; it does not change how $jsonSchema evaluates a write. Validators enforce identically at any supported FCV. FCV matters to the upgrade sequence — 7.0 expects the FCV to already be at 6.0 — but a rejection you see under one FCV you will see under the other, because the validation engine is the same code path.
Related
- Understanding MongoDB
$jsonSchemaSyntax — the parent guide to the keyword surface that is identical across 6.x and 7.x. - MongoDB JSON Schema Validation Architecture — the overarching enforcement contract these version-stable validators operate within.
- Using pattern and patternProperties for String Validation — the string-matching keywords whose behavior is unchanged between the two releases.
- JSON Schema Draft 4 vs Draft 2019 in MongoDB — why MongoDB stays on Draft 4 regardless of server version, and how to reconcile client tooling.
- Validating nested arrays with
$jsonSchema— element-level array constraints that also behave identically across the upgrade.
For the authoritative operator behavior referenced above, consult the official MongoDB schema-validation documentation.