[MongoDB] Difference Between Code 11000 and 11001 in E11000 duplicate key error index

Tadashi Shigeoka ·  Mon, September 14, 2015

In MongoDB version 2.4.5, there are error codes 11000 and 11001 when duplicate key error index errors occur due to unique indexes, so I investigated the difference between them.

MongoDB | モンゴディービー

Preparation

> db.version()
2.4.5

> db.so.drop();
> db.so.insert( { foo: 5 } );
> db.so.ensureIndex( { foo: 1 }, { unique: true } );
> db.so.insert( { foo: 6 } );

Case of Insert Method (New Addition)

When a duplicate key error index error occurs with db.collection.insert(), it returns error code 11000.

> db.so.insert( { foo: 5 } );
E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }

> db.getPrevError();
{
  "err" : "E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }",
  "code" : 11000,
  "n" : 0,
  "nPrev" : 1,
  "ok" : 1
}

Case of Update Methods (update / save)

When a duplicate key error index error occurs with update methods like db.collection.update() and db.collection.save(), it returns error code 11001.

What’s confusing here is that the error message E11000 duplicate key error index contains the error code 11000.

> db.so.update( { foo: 6 }, { $set: { foo: 5 } } );
E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }

> db.getPrevError();
{
  "err" : "E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }",
  "code" : 11001,
  "n" : 0,
  "nPrev" : 1,
  "ok" : 1
}
> var so6 = db.so.findOne( { foo: 6 } )
> so6.foo = 5
5

> db.so.save( so6 )
E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }

> db.getPrevError();
{
  "err" : "E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }",
  "code" : 11001,
  "n" : 0,
  "nPrev" : 1,
  "ok" : 1
}

Summary

In MongoDB version 2.4.5, the error message is the same (E11000 duplicate key error index), but there are two types of error codes, 11000 and 11001, which seems like buggy behavior.

Therefore, when you want to handle duplicate key errors in your program, you might want to handle it like if(err.code === 11000 || err.code === 11001).

When I tried this with MongoDB version 3.0.2, it appears the error codes have been unified to 11000.

So code that only checks for err.code === 11001 will stop working when MongoDB is upgraded, so caution is needed.

> db.version()
3.0.2

> db.so.insert( { foo: 5 } );
WriteResult({
  "nInserted" : 0,
  "writeError" : {
    "code" : 11000,
    "errmsg" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }"
  }
})

> db.so.update( { foo: 6 }, { $set: { foo: 5 } } );
WriteResult({
  "nMatched" : 0,
  "nUpserted" : 0,
  "nModified" : 0,
  "writeError" : {
    "code" : 11000,
    "errmsg" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }"
  }
})

> var so6 = db.so.findOne( { foo: 6 } )
> so6.foo = 5
5
> db.so.save( so6 )
WriteResult({
  "nMatched" : 0,
  "nUpserted" : 0,
  "nModified" : 0,
  "writeError" : {
    "code" : 11000,
    "errmsg" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }"
  }
})

That’s all.

Reference Information

That’s all from the Gemba.