Why does mongodb fail my json schema validation? I am using mongodb 3.6 and have below validator for the students collection:

rs1:PRIMARY&gt; db.getCollectionInfos({name: 'students'})
[
    {
        "name" : "students",
        "type" : "collection",
        "options" : {
            "validator" : {
                "$jsonSchema" : {
                    "properties" : {
                        "name" : {
                            "bsonType" : "string",
                            "description" : "name"
                        },
                        "age" : {
                            "bsonType" : "int",
                            "minimum" : 10,
                            "maximum" : 30
                        }
                    },
                    "required" : [
                        "name",
                        "age"
                    ],
                    "bsonType" : "object"
                }
            },
            "validationLevel" : "strict",
            "validationAction" : "error"
        },
        "info" : {
            "readOnly" : false,
            "uuid" : BinData(4,"111r7z+rQpGoebZ1jAHO4g==")
        },
        "idIndex" : {
            "v" : 2,
            "key" : {
                "_id" : 1
            },
            "name" : "_id_",
            "ns" : "test.students"
        }
    }
]


it requires two properties name and age. Name must be a string and age must be between 10 and 30. But why does below insert fail?

rs1:PRIMARY&gt; db.students.insert({age: 11, name: 'Mike'})
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
})
As I am able to see you are getting the insert writeError with Error code : 121 like that

"nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"


As per MongoDB blog documentation of @Jai Hirsch here for MongoDB document validation. 
Sometimes you want completely free form documents and sometimes you don’t. In the 3.2 release of MongoDB the idea of document validation was introduced.
One area I have encountered problems in the past is with dates being inserted using different data types.

Example: (command line notation used for brevity) 
The first team was using numeric dates:

 db.date.insert({date:20150321}) 


The second team was using string format:

db.date.insert({date:"03/21/2015"})


The third team was using ISO dates:

 db.date.insert({date:new Date('Mar 21, 2015')}) 


The communication issues that lead to this problem is a story for another time, but needless to say a fair amount of data cleanup was required to fix the issue as the primary application that read the data was expecting an ISO date.  The code issue was solved by using a shared library that defined the database mapping object.  Now let’s take a look at how document validation could be used to solve this problem.

We will create a collection with the following command:

db.createCollection( "date", {
    validator: { date: {$type:"date"}}
} )


With the collection created with the validator one can now only insert using the new Date() format:

db.date.insert({date:new Date('Mar 21, 2015')})


The numeric and string inserts will give the following error:

WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
})


likewise almost every developer new to MongoDB will make this "mistake" on the command line like: 

db.numbers.insert({number:2})


One would think that they have inserted a document containing the integer number two into the collection, when in fact the document now contains a floating-point value.

I can attest to the pain this can cause (especially if you are using a strongly typed language such as JAVA).

We can use the validator to safeguard against this:

db.createCollection( "numbers", {
    validator: { number: {$type:"int" }}
} )


The preceding insert will now give us the 121 error code and you need to use the NumberInt constructor:

db.numbers.insert({number:NumberInt(2)})