InletDownload

MongoDB error 121

Document failed validation

The collection has a validator, and the document your insert or update would produce breaks one of its rules. The error’s errInfo field says which rule and which field; fix the document, or change the rules if they’re wrong.

Document failed validation

Tested on MongoDB 8.0.32 (mongosh 2.12.0) · Updated 9 October 2026

What it means

The collection was created (or changed with collMod) with a validator: usually a $jsonSchema listing required fields and their types. MongoDB checks every insert, and every update’s result, against it. Yours didn’t pass, so the server refused the write with code 121 (DocumentValidationFailure).

The message itself never says why. The reason is in the error’s errInfo field: the rule that failed (required, bsonType, minimum…), the field, and the value MongoDB saw. Most shells and drivers print only the message, so you have to ask for errInfo.

Common causes

  1. A required field is missing, often one added to the schema after the code that writes it.
  2. A value has the wrong type. A price sent as the string "12.50" instead of a number, a date as a string instead of a Date, or an id as a string instead of an ObjectId.
  3. A value breaks a limit: minimum, maxLength, enum, pattern.
  4. An update produces an invalid document, such as $unset on a required field.
  5. An update touches a document that was already invalid. With the default validation level, strict, any update to it must leave it valid, even if the update changes another field.
  6. Extra fields, when the schema sets additionalProperties: false.

How to fix it

Read errInfo

In mongosh, catch the error and print errInfo:

try {
  db.products.insertOne({ name: "Lamp", price: "12.50" })
} catch (e) {
  printjson(e.errInfo)
}
{
  failingDocumentId: ObjectId('6ac8be6f4291c45852f84fcd'),
  details: {
    operatorName: '$jsonSchema',
    schemaRulesNotSatisfied: [
      {
        operatorName: 'properties',
        propertiesNotSatisfied: [
          {
            propertyName: 'price',
            details: [
              {
                operatorName: 'bsonType',
                specifiedAs: {
                  bsonType: [
                    'double',
                    'int',
                    'decimal'
                  ]
                },
                reason: 'type did not match',
                consideredValue: '12.50',
                consideredType: 'string'
              }
…

Here price must be a number and got a string. In application code, log the same field (errInfo on the Node.js driver’s error). For a missing field, details lists missingProperties.

Read the rules

db.getCollectionInfos({ name: "products" })[0].options

It shows the validator, and validationLevel and validationAction once they’ve been set. When they’re missing, the defaults apply: strict and error.

Fix the document

Send the right type (12.5, not "12.50"; new Date(…), not a date string), add the missing field, or keep the value in range. If your code builds documents from user input or JSON, convert types before writing.

Find documents that are already invalid

Documents written before the validator was added (or with validation bypassed) can break it. Find them with the validator itself:

const v = db.getCollectionInfos({ name: "products" })[0].options.validator
db.products.find({ $nor: [v] })

Fix them, or switch the level to moderate while you do: moderate still checks inserts and updates to valid documents, but lets updates to already-invalid ones through.

db.runCommand({ collMod: "products", validationLevel: "moderate" })

Change the rules if they’re wrong

collMod replaces the validator, or changes what happens on failure:

db.runCommand({ collMod: "products", validationAction: "warn" })

With warn, invalid writes succeed and the server logs Document would fail validation. That’s useful while you roll out a new schema; switch back to error afterwards.

Bypass validation only for a one-off fix

{ bypassDocumentValidation: true } on an insert or update skips the check. It needs the bypassDocumentValidation action (in the dbAdmin and restore roles), and later updates to that document must make it valid or bypass again.

Reproduce it

MongoDB 8.0.32 in Docker, mongosh 2.12.0:

db.createCollection("products", { validator: { $jsonSchema: {
  bsonType: "object",
  required: ["name", "price"],
  properties: {
    name: { bsonType: "string" },
    price: { bsonType: ["double", "int", "decimal"], minimum: 0 }
  }
} } })
db.products.insertOne({ name: "Lamp" })
MongoServerError: Document failed validation

The error’s code was 121. The insert with price: "12.50" gave the same message and the errInfo shown above. A raw insert command showed the failure inside writeErrors, with missingProperties: [ 'price' ]. $unset of price on a valid document was refused the same way.

With bypassDocumentValidation: true, the string price went in. Afterwards, updating only that document’s colour was refused under strict and allowed under moderate. With validationAction: "warn", an insert without price succeeded and the server log showed:

{"t":{"$date":"2026-10-09T10:14:24.429+00:00"},"s":"W",  "c":"STORAGE",  "id":20294,   "ctx":"conn93161","msg":"Document would fail validation","attr":{"namespace":"seo_mongo.products",…

In Inlet

Inlet shows MongoDB collections as tables and each document in the inspector, so you can compare documents that passed with what your code sends. Queries use mongosh syntax, so db.products.find({ $nor: [ … ] }) with the validator finds the documents that break it, and a refused write shows the server’s message.

Related

Sources