Debug E11000 Errors in Mongoose

Apr 29, 2019

MongoDB's E11000 error is a common source of confusion. This error occurs when two documents have the same value for a field that's defined as unique in your Mongoose schema.

Mongoose models have an _id field that's always unique. If you try to insert two documents with the same _id, you get the below error message.

MongoError: E11000 duplicate key error collection: test.customers index: _id_
dup key: { : ObjectId('5cc5ea092dca872442916cf5') }

The test.customers part represents the MongoDB collection that the error occurred in. The _id_ string is the name of the unique index, and the ObjectId() is the duplicate value.

The below code is one way you might get the above error message. MongoDB collections always have a unique index on _id, so trying to insert a document with a duplicate id will cause a duplicate key error.

const CharacterModel = mongoose.model('Character',
  new Schema({ name: String }));

const doc = await CharacterModel.create({ name: 'Jon Snow' });

doc._id; // Something like "5cc5e9be172acd237a893610"

try {
  // Try to create a document with the same `_id`. This will always fail
  // because MongoDB collections always have a unique index on `_id`.
  await CharacterModel.create(Object.assign({}, doc.toObject()));
} catch (error) {
  // MongoError: E11000 duplicate key error collection: test.characters
  // index: _id_ dup key: { : ObjectId('5cc5ea092dca872442916cf5') }
  error.message;
}

This error is often caused by null or undefined field values. null and undefined count as distinct values, so if you declare a field email as unique, two documents cannot have email = undefined. The below example creates two documents without an email property, which causes a duplicate key error.

const UserModel = mongoose.model('User', new Schema({
  name: String,
  email: {
    type: String,
    unique: true
  }
}));

// Wait for the index to build. The index name will be `email_1`
await UserModel.init();

// Create a document with no `email` set
await UserModel.create({ name: 'user 1' });

try {
  await UserModel.create({ name: 'user 2' });
} catch (error) {
  // E11000 duplicate key error collection: test.users index: email_1
  // dup key: { : null }
  error.message;
}

To make MongoDB E11000 error messages user-friendly, you should use the mongoose-beautiful-unique-validation plugin.

const schema = new Schema({ name: String });
schema.plugin(require('mongoose-beautiful-unique-validation'));

const CharacterModel = mongoose.model('Character', schema);

const doc = await CharacterModel.create({ name: 'Jon Snow' });

try {
  // Try to create a document with the same `_id`. This will always fail
  // because MongoDB collections always have a unique index on `_id`.
  await CharacterModel.create(Object.assign({}, doc.toObject()));
} catch (error) {
  // Path `_id` (5cc60c5603a95a15cfb9204d) is not unique.
  error.errors['_id'].message;
}

More Mongoose Tutorials