Introduction
Index creation is a critical operation for MongoDB performance, but builds can fail for various reasons. Duplicate key violations are the most common cause, preventing unique indexes from being created. Memory constraints, disk space, and concurrent operations can also interrupt index builds, requiring careful diagnosis and remediation to complete successful index creation.
Symptoms
Index build failures manifest with specific error codes:
```text # Duplicate key error (most common) MongoServerError: Index build failed: 86b310c3-45f1-4d0c-8b1e: collection scan halted due to duplicate keys
# Error code 67 - Cannot create unique index MongoError: E11000 duplicate key error collection: mydb.users index: email_1
# Memory constraint MongoServerError: Index build failed: out of memory
# Background index conflict MongoServerError: cannot build index on collection with background index build in progress
# In mongod.log {"msg":"Index build failed","attr":{"uuid":"xxx","error":"duplicate key detected"}} ```
Common Causes
- 1.Duplicate key values - Existing documents violate unique index constraint
- 2.Insufficient memory - Index build exceeds available memory
- 3.Concurrent index builds - Background index already running on collection
- 4.Disk space exhaustion - Index requires more space than available
- 5.Collection locked - Index build blocked by ongoing operations
- 6.Null values in unique index - Multiple documents with null in indexed field
Step-by-Step Fix
Step 1: Identify the Failure Type
Check the error message and log details:
```bash # Check MongoDB logs tail -100 /var/log/mongodb/mongod.log | grep -i "index"
# Current index build status mongosh --eval "db.currentOp({ 'createIndexes': { '$exists': true } })" ```
For duplicate key errors, identify the conflicting documents:
```javascript mongosh
// If error shows duplicate on email field use mydb db.users.find({}, { email: 1 }).sort({ email: 1 })
// Find specific duplicates db.users.aggregate([ { $group: { _id: "$email", count: { $sum: 1 }, docs: { $push: "$_id" } } }, { $match: { count: { $gt: 1 } } }, { $sort: { count: -1 } } ])
// For compound index duplicates db.users.aggregate([ { $group: { _id: { email: "$email", status: "$status" }, count: { $sum: 1 }, docs: { $push: "$_id" } }}, { $match: { count: { $gt: 1 } } } ]) ```
Step 2: Resolve Duplicate Keys
Option A: Remove duplicate documents:
// Keep newest document, remove older duplicates
db.users.aggregate([
{ $sort: { createdAt: -1 } },
{ $group: {
_id: "$email",
docId: { $first: "$_id" },
duplicates: { $push: "$_id" }
}},
{ $match: { duplicates: { $size: { $gt: 1 } } } }
]).forEach(function(doc) {
// Remove all except the first
doc.duplicates.slice(1).forEach(function(id) {
if (id.toString() !== doc.docId.toString()) {
db.users.deleteOne({ _id: id })
}
})
})Option B: Merge duplicate documents:
// Merge fields from duplicates into single document
db.users.aggregate([
{ $group: {
_id: "$email",
merged: { $mergeObjects: "$$ROOT" },
ids: { $push: "$_id" },
count: { $sum: 1 }
}},
{ $match: { count: { $gt: 1 } } }
]).forEach(function(doc) {
// Update first document with merged data
db.users.updateOne(
{ _id: doc.ids[0] },
{ $set: doc.merged }
)
// Remove duplicates
db.users.deleteMany({
_id: { $in: doc.ids.slice(1) },
email: doc._id
})
})Option C: Handle null/missing values:
```javascript // Find documents with null in indexed field db.users.find({ email: null }) db.users.find({ email: { $exists: false } })
// Set unique placeholder values db.users.updateMany( { email: null }, { $set: { email: "placeholder_" + ObjectId().toString() } } )
// Or use sparse index to skip nulls db.users.createIndex({ email: 1 }, { unique: true, sparse: true }) ```
Step 3: Retry Index Build
After resolving duplicates, retry the index:
```javascript // Build unique index db.users.createIndex({ email: 1 }, { unique: true })
// With options db.users.createIndex( { email: 1 }, { unique: true, sparse: true, // Skip null values background: true // Build without blocking (deprecated in 4.2+) } )
// Check build progress db.currentOp({ $or: [ { op: "command", "command.createIndexes": { $exists: true } }, { op: "none", ns: /users/ } ] }) ```
Step 4: Handle Memory Constraints
For large collections, build indexes incrementally:
```javascript // Check document count db.users.countDocuments()
// If collection is large (>1M docs), use smaller batch sizes // MongoDB automatically manages this, but ensure: // - WiredTiger cache is sufficient // - System memory available
// Check memory before building db.serverStatus().wiredTiger.cache
// Build during low-traffic periods // Monitor with: db.currentOp({ "createIndexes": { $exists: true } }) ```
Adjust WiredTiger cache if needed:
# In mongod.conf
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 8Step 5: Handle Concurrent Builds
MongoDB 4.2+ allows multiple index builds on same collection:
```javascript // Check running index builds db.currentOp({ $or: [ { op: "command", "command.createIndexes": { $exists: true } }, { op: "command", "command.createIndexes": { $exists: true } } ] })
// Wait for completion before retrying // Or kill hanging index build (dangerous!) db.killOp(<opId>) ```
For older MongoDB versions, build indexes one at a time:
// Check if any index is building
db.users.getIndexes().forEach(function(idx) {
let stats = db.users.aggregate([{ $indexStats: {} }])
// Check 'building' status in output
})Step 6: Verify Successful Build
```javascript // Confirm index exists db.users.getIndexes()
// Check index is usable db.users.find({ email: "test@example.com" }).explain()
// Verify no duplicates remain db.users.aggregate([ { $group: { _id: "$email", count: { $sum: 1 } } }, { $match: { count: { $gt: 1 } } } ])
// Check index size db.users.stats().indexSizes ```
Verification
Complete verification steps:
```javascript // 1. Index exists and is ready let indexes = db.users.getIndexes() indexes.forEach(i => printjson(i))
// 2. Unique constraint working db.users.insertOne({ email: "duplicate@example.com" }) // Should fail if email already exists
// 3. Query uses index let explain = db.users.find({ email: "test@example.com" }).explain() printjson(explain.queryPlanner.winningPlan) // Should show IXSCAN (index scan), not COLLSCAN
// 4. Index build complete in logs ```
Check in logs:
grep "Index build done" /var/log/mongodb/mongod.logCommon Pitfalls
- Not checking for duplicates before creating unique index - Always audit data first
- Building indexes during peak traffic - Schedule for low-traffic windows
- Ignoring sparse option for nullable fields - Null values violate unique constraints
- Not monitoring build progress - Large builds can take hours
- Killing index builds improperly - Can leave indexes in inconsistent state
Best Practices
- Audit data for duplicates before unique index creation
- Use sparse unique indexes when fields can be null
- Build indexes during maintenance windows for large collections
- Monitor index build progress with
db.currentOp() - Test index creation on staging environment first
- Document index creation time estimates for capacity planning
Related Issues
- MongoDB Duplicate Key Error
- MongoDB Slow Query Analysis
- MongoDB Memory Limit Exceeded
- MongoDB WiredTiger Cache Full
Related Articles
- [Database troubleshooting: Fix Backup Exclusive Lock Table Production Writes ](backup-exclusive-lock-table-production-writes)
- [Fix Connection Pool Leak Application Not Closing Issue in Database](connection-pool-leak-application-not-closing)
- [Fix Connection Reset Idle Timeout Firewall Issue in Database](connection-reset-idle-timeout-firewall)
- [Fix Connection Reset Idle Timeout Serverless Database Issue in Database](connection-reset-idle-timeout-serverless-database)
- [Fix Connection String Encoding Special Characters Issue in Database](connection-string-encoding-special-characters)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "MongoDB Index Build Failed", "description": "Resolve MongoDB index build failures. Handle duplicate key errors, memory constraints, and background index conflicts.", "url": "https://www.fixwikihub.com/fix-mongodb-index-build-failed", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-15T10:45:05.029Z", "dateModified": "2025-11-15T10:45:05.029Z" } </script>