Skip to content
MongoDB

MongoDB Error 121

Document failed validation

Applies to: MongoDB 7.0 and 8.0 (format checked against the 8.0 source and documentation)
Last technically reviewed 24 October 2026 on MongoDB 8.0 documentation and source (error_codes.yml r8.0.0); not run locally
The full message
MongoServerError: Document failed validation
Other forms of this message
mongosh prints the details after the message (schema validation documentation)
Additional information: {
  failingDocumentId: ObjectId("6377cca4aac957f2b77ea955"),
  details: {
    operatorName: '$jsonSchema',
    schemaRulesNotSatisfied: [ ... ]
  }
}
Server log entry when the collection uses validationAction "warn" (log id 20294; the write is accepted)
"msg": "Document would fail validation"
Error code
121
Code name
DocumentValidationFailure
Product
MongoDB
Versions
MongoDB 7.0 and 8.0 (format checked against the 8.0 source and documentation)
Last reviewed
24 October 2026

What it means

Error 121 (DocumentValidationFailure) means an insert or update would leave a document that breaks the collection's validator, such as a $jsonSchema rule, so MongoDB rejected the write.

A collection can carry a validator: a $jsonSchema document or query operators that every inserted or updated document must satisfy. With the default validationAction: "error", a write that produces a document the validator does not match is rejected with code 121 and the fixed message Document failed validation (the string is a constant in MongoDB 8.0's collection code). The message never says which rule failed; the answer is in the errInfo document that comes with it, which mongosh prints as Additional information.

errInfo.failingDocumentId is the document's _id and errInfo.details is a tree of the rules that were not satisfied. Read it from the leaves: missingProperties lists required fields that are absent, propertiesNotSatisfied names each field that failed with a reason such as type did not match or regular expression did not match, and consideredValue and consideredType show what was actually sent. With additionalProperties: false the unexpected fields are listed under additionalProperties.

The validation level decides which writes are checked. The default strict checks every insert and update; moderate does not check updates to documents that were already invalid. MongoDB documents that adding or tightening rules does not check existing documents, but later updates to an invalid document fail until the document is made valid. A validator that uses only query operators (not $jsonSchema) reports failures with reasons such as field was missing.

Common causes

  • A field listed in required is missing from the document (shown under missingProperties).
  • A field has the wrong BSON type: a string where a number is expected, a date sent as a string, or a whole number stored as int where the rule says bsonType: "double".
  • A value breaks a constraint such as pattern, enum, minimum, maximum or maxLength.
  • The schema sets additionalProperties: false and the document contains a field the schema does not list.
  • An update touches a document that was stored before the rules were added or tightened, and the result still breaks the current rules.
  • The validator was changed (collMod or a migration) and the application was not updated to match.

Diagnose it

Read-only These mongosh commands only read data, indexes, statistics and server state (find, aggregate without $out or $merge, getIndexes, stats, currentOp, rs.status). They do not change data, users or settings, so they are safe to run first.

Show the collection's validator, level and action

db.getCollectionInfos({ name: "contacts" })[0].options
What to look for

The validator document, plus validationLevel and validationAction when they were set explicitly (MongoDB omits them from this output when they are the defaults, strict and error). Compare each rule with the field named in errInfo.

Test a document against the validator without writing it

const v = db.getCollectionInfos({ name: "contacts" })[0].options.validator
const candidate = { name: "Amanda", email: "amanda@xyz.com" }

db.aggregate([ { $documents: [ candidate ] }, { $match: v } ])
What to look for

The document comes back when it satisfies the validator and nothing comes back when it does not. Remove or change one field at a time to find the failing rule. Nothing is stored: $documents only feeds the pipeline.

Find existing documents that break the current rules

const v = db.getCollectionInfos({ name: "contacts" })[0].options.validator

db.contacts.find({ $nor: [ v ] }).limit(20)
db.contacts.countDocuments({ $nor: [ v ] })
What to look for

Documents stored before the rules were added or changed. MongoDB's schema validation documentation uses this $nor pattern; updates to these documents fail with 121 until they are made valid.

Check the stored type of a field

db.contacts.aggregate([
  { $group: { _id: { $type: "$phone" }, docs: { $sum: 1 } } }
])
What to look for

How many documents hold each type for the field (for example string, int, double or missing). A mix of types usually explains a type did not match reason.

How to fix it

Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.

Send a document that matches the rules

Client or network side

When the rule is right, fix the data at the source: add the missing field, send the right type (a real Date rather than a date string, a number rather than a numeric string) and validate input before the write. In code, catch code 121 and show the fields from errInfo.details instead of the bare message.

db.contacts.insertOne({
  name: "Amanda",
  phone: "+44 20 7946 0000",
  email: "amanda@mongodb.com"
})

Correct a rule that is too strict

Changes schema

When the rule itself is wrong, change it with collMod. A common case is bsonType: "double" for a field that also receives whole numbers, which mongosh and many drivers store as int: the "number" alias accepts int, long, double and decimal. Repeat the whole validator in collMod, because the new one replaces the old one.

Caution: The new validator applies to every later write by every application. Agree the change with the owners of the collection, keep the old validator (from getCollectionInfos) so it can be restored, and test it first with the $documents check above.

db.runCommand({
  collMod: "products",
  validator: { $jsonSchema: {
    bsonType: "object",
    required: [ "name", "price" ],
    properties: {
      name:  { bsonType: "string" },
      price: { bsonType: "number", minimum: 0 }
    }
  } }
})

Repair documents that were stored before the rules

Changes data

When updates fail because the stored document is already invalid, bring the old documents into line first. Review the $nor results above, then fix them with a targeted update that supplies the missing or corrected value.

Caution: Check the filter with countDocuments first and agree the placeholder value with the data owner: a bulk update changes every matching document.

db.contacts.updateMany(
  { phone: { $exists: false } },
  { $set: { phone: "unknown" } }
)

Bypass validation for a one-off restore

Changes data

For restoring old data that predates the rules, the insert, update, findAndModify and aggregate ($out, $merge) commands accept bypassDocumentValidation: true. The user needs the bypassDocumentValidation action, which the built-in dbAdmin and restore roles provide.

Caution: This is not a fix for application writes. The bypassed documents stay invalid: MongoDB documents that later updates to them must also bypass validation or produce a valid document, so they will raise 121 again. Record which documents were loaded this way.

db.runCommand({
  insert: "contacts",
  documents: [ { name: "Old record", email: "old@example.com" } ],
  bypassDocumentValidation: true
})

Examples

A missing required field and a value that breaks a pattern

Not reproduced here: no MongoDB server is installed for this site. The example and the result are the ones in MongoDB's documentation page "Choose How to Handle Invalid Documents"; the ObjectId is generated by the server and differs on every insert.

db.createCollection("contacts", {
  validator: { $jsonSchema: {
    bsonType: "object",
    required: [ "phone" ],
    properties: {
      phone: { bsonType: "string", description: "must be a string and is required" },
      email: { bsonType: "string", pattern: "@mongodb\\.com$",
               description: "must be a string and end with '@mongodb.com'" }
    }
  } },
  validationAction: "error"
})

db.contacts.insertOne({ name: "Amanda", email: "amanda@xyz.com" })
Expected result (documented format, not run)
MongoServerError: Document failed validation
Additional information: {
  failingDocumentId: ObjectId("6377cca4aac957f2b77ea955"),
  details: {
    operatorName: '$jsonSchema',
    schemaRulesNotSatisfied: [
      {
        operatorName: 'properties',
        propertiesNotSatisfied: [
          {
            propertyName: 'email',
            description: "must be a string and end with '@mongodb.com'",
            details: [
              {
                operatorName: 'pattern',
                specifiedAs: { pattern: '@mongodb\\.com$' },
                reason: 'regular expression did not match',
                consideredValue: 'amanda@xyz.com'
              }
            ]
          }
        ]
      },
      {
        operatorName: 'required',
        specifiedAs: { required: [ 'phone' ] },
        missingProperties: [ 'phone' ]
      }
    ]
  }
}

A whole number where the rule says double

Not reproduced here: no MongoDB server is installed for this site. The detail fields (reason "type did not match", consideredValue, consideredType) are the ones built by MongoDB 8.0's validation error code (doc_validation_error.cpp, generateTypeError); MongoDB's "Query for and Modify Valid or Invalid Documents" page shows whole numbers entered in mongosh failing a double rule. The layout follows the documented example above and the ObjectId is left out.

db.createCollection("products", {
  validator: { $jsonSchema: {
    bsonType: "object",
    required: [ "name", "price" ],
    properties: {
      name:  { bsonType: "string" },
      price: { bsonType: "double" }
    }
  } }
})

db.products.insertOne({ name: "Pen", price: 2 })     // 2 is stored as int
Expected result (documented format, not run)
MongoServerError: Document failed validation
Additional information: {
  failingDocumentId: ObjectId("..."),
  details: {
    operatorName: '$jsonSchema',
    schemaRulesNotSatisfied: [
      {
        operatorName: 'properties',
        propertiesNotSatisfied: [
          {
            propertyName: 'price',
            details: [
              {
                operatorName: 'bsonType',
                specifiedAs: { bsonType: 'double' },
                reason: 'type did not match',
                consideredValue: 2,
                consideredType: 'int'
              }
            ]
          }
        ]
      }
    ]
  }
}

How to prevent it

Keep the validator in version control next to the application code, change it with collMod in the same release as the code that depends on it, and run the $nor query before tightening a rule so you know how many stored documents will start failing on update.

Use the "number" alias unless a field really must be one numeric type, send dates as Date values, and log errInfo (not just the message) whenever a write fails with code 121.

Common questions

How do I see why a MongoDB document failed validation?

Read errInfo, not the message. mongosh prints it as Additional information; drivers return it as the errInfo field of the write error. Look for missingProperties and for each propertyName with its reason, consideredValue and consideredType.

Why does an update fail validation when I did not change the invalid field?

The whole resulting document is checked, not only the fields you changed. If the document was stored before the rules were added, it is still invalid after your update, so the update is rejected under the default strict level. Fix the old field in the same update or repair those documents first.

Should I set validationAction to warn to stop error 121?

Not as a fix. With warn, invalid documents are accepted and only logged, so the problem moves into your data. Correct the document or the rule instead; warn is for a planned migration where the log is reviewed.

Learn more on CodeWithSQL

Official documentation

Last technically reviewed 24 October 2026; examples and diagnostics run on MongoDB 8.0 documentation and source (error_codes.yml r8.0.0); not run locally. Codes and code names are checked against MongoDB's error_codes.yml (8.0); no MongoDB server was available, so the examples were not run locally.

Still stuck on a MongoDB error?

Browse the full MongoDB error library, or get hands-on help from an experienced SQL professional.