diff --git a/src/mongo/db/storage/biggie/biggie_kv_engine.cpp b/src/mongo/db/storage/biggie/biggie_kv_engine.cpp
index b99d45ccd1c20b39161ac885b1c55d11c8c4119b..7c79a822d0396812333c7fad4056407450cc993f 100644
--- a/src/mongo/db/storage/biggie/biggie_kv_engine.cpp
+++ b/src/mongo/db/storage/biggie/biggie_kv_engine.cpp
@@ -94,7 +94,11 @@ Status KVEngine::createSortedDataInterface(OperationContext* opCtx,
 mongo::SortedDataInterface* KVEngine::getSortedDataInterface(OperationContext* opCtx,
                                                              StringData ident,
                                                              const IndexDescriptor* desc) {
-    return new SortedDataInterface(Ordering::make(desc->keyPattern()), desc->unique(), ident);
+    return new SortedDataInterface(Ordering::make(desc->keyPattern()),
+                                   desc->unique(),
+                                   ident,
+                                   desc->parentNS(),
+                                   desc->indexName());
 }
 
 
diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp b/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
index 6dc78eb4e0682dad49f1982fec46c740f6ee2120..e7ce7750c79279f321202f5264f8d8e1e9f31897 100644
--- a/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
+++ b/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
@@ -83,13 +83,6 @@ BSONObj stripFieldNames(const BSONObj& obj) {
     return bob.obj();
 }
 
-Status dupKeyError(const BSONObj& key) {
-    StringBuilder sb;
-    sb << "E11000 duplicate key error ";
-    sb << "dup key: " << key;
-    return Status(ErrorCodes::DuplicateKey, sb.str());
-}
-
 // This function converts a key and an ordering to a KeyString.
 std::unique_ptr<KeyString> keyToKeyString(const BSONObj& key, Ordering order) {
     KeyString::Version version = KeyString::Version::V1;
@@ -220,13 +213,17 @@ int compareTwoKeys(
 SortedDataBuilderInterface::SortedDataBuilderInterface(OperationContext* opCtx,
                                                        bool dupsAllowed,
                                                        Ordering order,
-                                                       std::string prefix,
-                                                       std::string identEnd)
+                                                       const std::string& prefix,
+                                                       const std::string& identEnd,
+                                                       const std::string& collectionNamespace,
+                                                       const std::string& indexName)
     : _opCtx(opCtx),
       _dupsAllowed(dupsAllowed),
       _order(order),
       _prefix(prefix),
       _identEnd(identEnd),
+      _collectionNamespace(collectionNamespace),
+      _indexName(indexName),
       _hasLast(false),
       _lastKeyToString(""),
       _lastRID(-1) {}
@@ -261,7 +258,7 @@ StatusWith<SpecialFormatInserted> SortedDataBuilderInterface::addKey(const BSONO
                       "expected ascending (key, RecordId) order in bulk builder");
     }
     if (!_dupsAllowed && twoKeyCmp == 0 && twoRIDCmp != 0) {
-        return dupKeyError(key);
+        return dupKeyError(key, _collectionNamespace, _indexName);
     }
 
     std::string workingCopyInsertKey = combineKeyAndRID(key, loc, _prefix, _order);
@@ -283,18 +280,25 @@ StatusWith<SpecialFormatInserted> SortedDataBuilderInterface::addKey(const BSONO
 
 SortedDataBuilderInterface* SortedDataInterface::getBulkBuilder(OperationContext* opCtx,
                                                                 bool dupsAllowed) {
-    return new SortedDataBuilderInterface(opCtx, dupsAllowed, _order, _prefix, _identEnd);
+    return new SortedDataBuilderInterface(
+        opCtx, dupsAllowed, _order, _prefix, _identEnd, _collectionNamespace, _indexName);
 }
 
 // We append \1 to all idents we get, and therefore the KeyString with ident + \0 will only be
 // before elements in this ident, and the KeyString with ident + \2 will only be after elements in
 // this ident.
-SortedDataInterface::SortedDataInterface(const Ordering& ordering, bool isUnique, StringData ident)
+SortedDataInterface::SortedDataInterface(const Ordering& ordering,
+                                         bool isUnique,
+                                         StringData ident,
+                                         const std::string& collectionNamespace,
+                                         const std::string& indexName)
     : _order(ordering),
       // All entries in this ident will have a prefix of ident + \1.
       _prefix(ident.toString().append(1, '\1')),
       // Therefore, the string ident + \2 will be greater than all elements in this ident.
       _identEnd(ident.toString().append(1, '\2')),
+      _collectionNamespace(collectionNamespace),
+      _indexName(indexName),
       _isUnique(isUnique) {
     // This is the string representation of the KeyString before elements in this ident, which is
     // ident + \0. This is before all elements in this ident.
@@ -340,7 +344,7 @@ StatusWith<SpecialFormatInserted> SortedDataInterface::insert(OperationContext*
             auto ks1 = keyToKeyString(ike.key, _order);
             auto ks2 = keyToKeyString(key, _order);
             if (ks1->compare(*ks2) == 0 && ike.loc.repr() != loc.repr()) {
-                return dupKeyError(key);
+                return dupKeyError(key, _collectionNamespace, _indexName);
             }
         }
     }
@@ -398,7 +402,7 @@ Status SortedDataInterface::dupKeyCheck(OperationContext* opCtx,
         lowerBoundIterator->first.compare(_KSForIdentEnd) < 0 &&
         lowerBoundIterator->first.compare(
             combineKeyAndRID(key, RecordId::max(), _prefix, _order)) <= 0) {
-        return dupKeyError(key);
+        return dupKeyError(key, _collectionNamespace, _indexName);
     }
     return Status::OK();
 }
diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl.h b/src/mongo/db/storage/biggie/biggie_sorted_impl.h
index 8ebf74a8c9363ee7a0aa385b99193a6bf9e58e64..09a049981c41dad7a1741d13271b2c0f9a250fee 100644
--- a/src/mongo/db/storage/biggie/biggie_sorted_impl.h
+++ b/src/mongo/db/storage/biggie/biggie_sorted_impl.h
@@ -41,8 +41,10 @@ public:
     SortedDataBuilderInterface(OperationContext* opCtx,
                                bool dupsAllowed,
                                Ordering order,
-                               std::string prefix,
-                               std::string identEnd);
+                               const std::string& prefix,
+                               const std::string& identEnd,
+                               const std::string& collectionNamespace,
+                               const std::string& indexName);
     SpecialFormatInserted commit(bool mayInterrupt) override;
     virtual StatusWith<SpecialFormatInserted> addKey(const BSONObj& key, const RecordId& loc);
 
@@ -54,6 +56,9 @@ private:
     // Prefix and identEnd for the ident.
     std::string _prefix;
     std::string _identEnd;
+    // Index metadata.
+    const std::string _collectionNamespace;
+    const std::string _indexName;
     // Whether or not we've already added something before.
     bool _hasLast;
     // This is the KeyString of the last key added.
@@ -67,7 +72,11 @@ public:
     // Truncate is not required at the time of writing but will be when the truncate command is
     // created
     Status truncate(OperationContext* opCtx);
-    SortedDataInterface(const Ordering& ordering, bool isUnique, StringData ident);
+    SortedDataInterface(const Ordering& ordering,
+                        bool isUnique,
+                        StringData ident,
+                        const std::string& collectionNamespace,
+                        const std::string& indexName);
     virtual SortedDataBuilderInterface* getBulkBuilder(OperationContext* opCtx,
                                                        bool dupsAllowed) override;
     virtual StatusWith<SpecialFormatInserted> insert(OperationContext* opCtx,
@@ -168,6 +177,9 @@ private:
     // These two are the same as before.
     std::string _prefix;
     std::string _identEnd;
+    // Index metadata.
+    const std::string _collectionNamespace;
+    const std::string _indexName;
     // These are the keystring representations of the _prefix and the _identEnd.
     std::string _KSForIdentStart;
     std::string _KSForIdentEnd;
diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl_test.cpp b/src/mongo/db/storage/biggie/biggie_sorted_impl_test.cpp
index 6fdcb589627dbfc9853004445965356293ad1572..68a82231ddd2cf9aa5eb9434ad9b53356c01b4b7 100644
--- a/src/mongo/db/storage/biggie/biggie_sorted_impl_test.cpp
+++ b/src/mongo/db/storage/biggie/biggie_sorted_impl_test.cpp
@@ -47,7 +47,8 @@ private:
 public:
     SortedDataInterfaceTestHarnessHelper() : _order(Ordering::make(BSONObj())) {}
     std::unique_ptr<mongo::SortedDataInterface> newSortedDataInterface(bool unique) final {
-        return std::make_unique<SortedDataInterface>(_order, unique, "ident"_sd);
+        return std::make_unique<SortedDataInterface>(
+            _order, unique, "ident"_sd, "test.biggie", "indexName");
     }
     std::unique_ptr<mongo::RecoveryUnit> newRecoveryUnit() final {
         //! not correct lol
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp
index 1f7b8a02f26672e3544a4bec3b929bc4769e5446..aafbf42a1485d37f43e520bc6e9d8c4071904e0d 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp
@@ -70,15 +70,6 @@ BSONObj stripFieldNames(const BSONObj& query) {
 
 typedef std::set<IndexKeyEntry, IndexEntryComparison> IndexSet;
 
-// taken from btree_logic.cpp
-Status dupKeyError(const BSONObj& key) {
-    StringBuilder sb;
-    sb << "E11000 duplicate key error ";
-    // sb << "index: " << _indexName << " "; // TODO
-    sb << "dup key: " << key;
-    return Status(ErrorCodes::DuplicateKey, sb.str());
-}
-
 bool isDup(const IndexSet& data, const BSONObj& key, RecordId loc) {
     const IndexSet::const_iterator it = data.find(IndexKeyEntry(key, RecordId()));
     if (it == data.end())
@@ -90,11 +81,17 @@ bool isDup(const IndexSet& data, const BSONObj& key, RecordId loc) {
 
 class EphemeralForTestBtreeBuilderImpl : public SortedDataBuilderInterface {
 public:
-    EphemeralForTestBtreeBuilderImpl(IndexSet* data, long long* currentKeySize, bool dupsAllowed)
+    EphemeralForTestBtreeBuilderImpl(IndexSet* data,
+                                     long long* currentKeySize,
+                                     bool dupsAllowed,
+                                     const std::string& collectionNamespace,
+                                     const std::string& indexName)
         : _data(data),
           _currentKeySize(currentKeySize),
           _dupsAllowed(dupsAllowed),
-          _comparator(_data->key_comp()) {
+          _comparator(_data->key_comp()),
+          _collectionNamespace(collectionNamespace),
+          _indexName(indexName) {
         invariant(_data->empty());
     }
 
@@ -111,7 +108,7 @@ public:
                 return Status(ErrorCodes::InternalError,
                               "expected ascending (key, RecordId) order in bulk builder");
             } else if (!_dupsAllowed && cmp == 0 && loc != _last->loc) {
-                return dupKeyError(key);
+                return dupKeyError(key, _collectionNamespace, _indexName);
             }
         }
 
@@ -129,16 +126,27 @@ private:
 
     IndexEntryComparison _comparator;  // used by the bulk builder to detect duplicate keys
     IndexSet::const_iterator _last;    // or (key, RecordId) ordering violations
+
+    const std::string _collectionNamespace;
+    const std::string _indexName;
 };
 
 class EphemeralForTestBtreeImpl : public SortedDataInterface {
 public:
-    EphemeralForTestBtreeImpl(IndexSet* data, bool isUnique) : _data(data), _isUnique(isUnique) {
+    EphemeralForTestBtreeImpl(IndexSet* data,
+                              bool isUnique,
+                              const std::string& collectionNamespace,
+                              const std::string& indexName)
+        : _data(data),
+          _isUnique(isUnique),
+          _collectionNamespace(collectionNamespace),
+          _indexName(indexName) {
         _currentKeySize = 0;
     }
 
     virtual SortedDataBuilderInterface* getBulkBuilder(OperationContext* opCtx, bool dupsAllowed) {
-        return new EphemeralForTestBtreeBuilderImpl(_data, &_currentKeySize, dupsAllowed);
+        return new EphemeralForTestBtreeBuilderImpl(
+            _data, &_currentKeySize, dupsAllowed, _collectionNamespace, _indexName);
     }
 
     virtual StatusWith<SpecialFormatInserted> insert(OperationContext* opCtx,
@@ -151,7 +159,7 @@ public:
 
         // TODO optimization: save the iterator from the dup-check to speed up insert
         if (!dupsAllowed && isDup(*_data, key, loc))
-            return dupKeyError(key);
+            return dupKeyError(key, _collectionNamespace, _indexName);
 
         IndexKeyEntry entry(key.getOwned(), loc);
         if (_data->insert(entry).second) {
@@ -197,7 +205,7 @@ public:
     virtual Status dupKeyCheck(OperationContext* opCtx, const BSONObj& key, const RecordId& loc) {
         invariant(!hasFieldNames(key));
         if (isDup(*_data, key, loc))
-            return dupKeyError(key);
+            return dupKeyError(key, _collectionNamespace, _indexName);
         return Status::OK();
     }
 
@@ -492,6 +500,9 @@ private:
     IndexSet* _data;
     long long _currentKeySize;
     const bool _isUnique;
+
+    const std::string _collectionNamespace;
+    const std::string _indexName;
 };
 }  // namespace
 
@@ -499,12 +510,15 @@ private:
 // factories. We don't actually modify it.
 SortedDataInterface* getEphemeralForTestBtreeImpl(const Ordering& ordering,
                                                   bool isUnique,
+                                                  const std::string& collectionNamespace,
+                                                  const std::string& indexName,
                                                   std::shared_ptr<void>* dataInOut) {
     invariant(dataInOut);
     if (!*dataInOut) {
         *dataInOut = std::make_shared<IndexSet>(IndexEntryComparison(ordering));
     }
-    return new EphemeralForTestBtreeImpl(static_cast<IndexSet*>(dataInOut->get()), isUnique);
+    return new EphemeralForTestBtreeImpl(
+        static_cast<IndexSet*>(dataInOut->get()), isUnique, collectionNamespace, indexName);
 }
 
 }  // namespace mongo
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.h b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.h
index 9d44e3e80cd2e4c6489db91fc79c6d85ed936dd1..57432888662fd4f9b3f87753156fca6d7909fec5 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.h
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.h
@@ -43,6 +43,8 @@ class IndexCatalogEntry;
  */
 SortedDataInterface* getEphemeralForTestBtreeImpl(const Ordering& ordering,
                                                   bool isUnique,
+                                                  const std::string& collectionNamespace,
+                                                  const std::string& indexName,
                                                   std::shared_ptr<void>* dataInOut);
 
 }  // namespace mongo
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl_test.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl_test.cpp
index 700628c4331f1e57ab0d7bed08282d1c8280368c..21c943a2fd9cedfd049f46d744e92d3cc2bc87d4 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl_test.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl_test.cpp
@@ -44,8 +44,8 @@ public:
     EphemeralForBtreeImplTestHarnessHelper() : _order(Ordering::make(BSONObj())) {}
 
     std::unique_ptr<SortedDataInterface> newSortedDataInterface(bool unique) final {
-        return std::unique_ptr<SortedDataInterface>(
-            getEphemeralForTestBtreeImpl(_order, unique, &_data));
+        return std::unique_ptr<SortedDataInterface>(getEphemeralForTestBtreeImpl(
+            _order, unique, "test.EphemeralForTest", "indexName", &_data));
     }
 
     std::unique_ptr<RecoveryUnit> newRecoveryUnit() final {
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp
index 0bc0f4f84129d528866243e81a80ddd5d4d5226f..b8814c3bdd067ba6034892f096e2663a782a2475 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp
@@ -89,8 +89,11 @@ SortedDataInterface* EphemeralForTestEngine::getSortedDataInterface(OperationCon
                                                                     StringData ident,
                                                                     const IndexDescriptor* desc) {
     stdx::lock_guard<stdx::mutex> lk(_mutex);
-    return getEphemeralForTestBtreeImpl(
-        Ordering::make(desc->keyPattern()), desc->unique(), &_dataMap[ident]);
+    return getEphemeralForTestBtreeImpl(Ordering::make(desc->keyPattern()),
+                                        desc->unique(),
+                                        desc->parentNS(),
+                                        desc->indexName(),
+                                        &_dataMap[ident]);
 }
 
 Status EphemeralForTestEngine::dropIdent(OperationContext* opCtx, StringData ident) {
diff --git a/src/mongo/db/storage/mobile/mobile_index.cpp b/src/mongo/db/storage/mobile/mobile_index.cpp
index 0eec0ce72d867916145ea5e9dfa06403f949d60b..3c5000c4929153bbca0d589f62ab340c15031672 100644
--- a/src/mongo/db/storage/mobile/mobile_index.cpp
+++ b/src/mongo/db/storage/mobile/mobile_index.cpp
@@ -72,7 +72,11 @@ BSONObj stripFieldNames(const BSONObj& query) {
 MobileIndex::MobileIndex(OperationContext* opCtx,
                          const IndexDescriptor* desc,
                          const std::string& ident)
-    : _isUnique(desc->unique()), _ordering(Ordering::make(desc->keyPattern())), _ident(ident) {}
+    : _isUnique(desc->unique()),
+      _ordering(Ordering::make(desc->keyPattern())),
+      _ident(ident),
+      _collectionNamespace(desc->parentNS()),
+      _indexName(desc->indexName()) {}
 
 StatusWith<SpecialFormatInserted> MobileIndex::insert(OperationContext* opCtx,
                                                       const BSONObj& key,
@@ -109,7 +113,7 @@ StatusWith<SpecialFormatInserted> MobileIndex::doInsert(OperationContext* opCtx,
             // Return error if duplicate key inserted in a unique index.
             BSONObj bson =
                 KeyString::toBson(key.getBuffer(), key.getSize(), _ordering, key.getTypeBits());
-            return _dupKeyError(bson);
+            return dupKeyError(bson, _collectionNamespace, _indexName);
         } else {
             // A record with same key could already be present in a standard index, that is OK. This
             // can happen when building a background index while documents are being written in
@@ -239,7 +243,7 @@ Status MobileIndex::dupKeyCheck(OperationContext* opCtx,
     invariant(_isUnique);
 
     if (_isDup(opCtx, key, recId))
-        return _dupKeyError(key);
+        return dupKeyError(key, _collectionNamespace, _indexName);
     return Status::OK();
 }
 
@@ -273,18 +277,18 @@ bool MobileIndex::_isDup(OperationContext* opCtx, const BSONObj& key, RecordId r
     return isEntryFound;
 }
 
-Status MobileIndex::_dupKeyError(const BSONObj& key) {
-    StringBuilder sb;
-    sb << "E11000 duplicate key error ";
-    sb << "index: " << _ident << " ";
-    sb << "dup key: " << key;
-    return Status(ErrorCodes::DuplicateKey, sb.str());
-}
-
 class MobileIndex::BulkBuilderBase : public SortedDataBuilderInterface {
 public:
-    BulkBuilderBase(MobileIndex* index, OperationContext* opCtx, bool dupsAllowed)
-        : _index(index), _opCtx(opCtx), _dupsAllowed(dupsAllowed) {}
+    BulkBuilderBase(MobileIndex* index,
+                    OperationContext* opCtx,
+                    bool dupsAllowed,
+                    const std::string& collectionNamespace,
+                    const std::string& indexName)
+        : _index(index),
+          _opCtx(opCtx),
+          _dupsAllowed(dupsAllowed),
+          _collectionNamespace(collectionNamespace),
+          _indexName(indexName) {}
 
     virtual ~BulkBuilderBase() {}
 
@@ -314,7 +318,7 @@ protected:
     Status _checkNextKey(const BSONObj& key) {
         const int cmp = key.woCompare(_lastKey, _index->getOrdering());
         if (!_dupsAllowed && cmp == 0) {
-            return _index->_dupKeyError(key);
+            return dupKeyError(key, _collectionNamespace, _indexName);
         } else if (cmp < 0) {
             return Status(ErrorCodes::InternalError, "expected higher RecordId in bulk builder");
         }
@@ -328,6 +332,8 @@ protected:
     OperationContext* const _opCtx;
     BSONObj _lastKey;
     const bool _dupsAllowed;
+    const std::string _collectionNamespace;
+    const std::string _indexName;
 };
 
 /**
@@ -335,8 +341,12 @@ protected:
  */
 class MobileIndex::BulkBuilderStandard final : public BulkBuilderBase {
 public:
-    BulkBuilderStandard(MobileIndex* index, OperationContext* opCtx, bool dupsAllowed)
-        : BulkBuilderBase(index, opCtx, dupsAllowed) {}
+    BulkBuilderStandard(MobileIndex* index,
+                        OperationContext* opCtx,
+                        bool dupsAllowed,
+                        const std::string& collectionNamespace,
+                        const std::string& indexName)
+        : BulkBuilderBase(index, opCtx, dupsAllowed, collectionNamespace, indexName) {}
 
 protected:
     StatusWith<SpecialFormatInserted> _addKey(const BSONObj& key, const RecordId& recId) override {
@@ -351,8 +361,12 @@ protected:
  */
 class MobileIndex::BulkBuilderUnique : public BulkBuilderBase {
 public:
-    BulkBuilderUnique(MobileIndex* index, OperationContext* opCtx, bool dupsAllowed)
-        : BulkBuilderBase(index, opCtx, dupsAllowed) {
+    BulkBuilderUnique(MobileIndex* index,
+                      OperationContext* opCtx,
+                      bool dupsAllowed,
+                      const std::string& collectionNamespace,
+                      const std::string& indexName)
+        : BulkBuilderBase(index, opCtx, dupsAllowed, collectionNamespace, indexName) {
         // Replication is not supported so dups are not allowed.
         invariant(!dupsAllowed);
     }
@@ -652,7 +666,7 @@ MobileIndexStandard::MobileIndexStandard(OperationContext* opCtx,
 SortedDataBuilderInterface* MobileIndexStandard::getBulkBuilder(OperationContext* opCtx,
                                                                 bool dupsAllowed) {
     invariant(dupsAllowed);
-    return new BulkBuilderStandard(this, opCtx, dupsAllowed);
+    return new BulkBuilderStandard(this, opCtx, dupsAllowed, _collectionNamespace, _indexName);
 }
 
 std::unique_ptr<SortedDataInterface::Cursor> MobileIndexStandard::newCursor(OperationContext* opCtx,
@@ -690,7 +704,7 @@ SortedDataBuilderInterface* MobileIndexUnique::getBulkBuilder(OperationContext*
                                                               bool dupsAllowed) {
     // Replication is not supported so dups are not allowed.
     invariant(!dupsAllowed);
-    return new BulkBuilderUnique(this, opCtx, dupsAllowed);
+    return new BulkBuilderUnique(this, opCtx, dupsAllowed, _collectionNamespace, _indexName);
 }
 
 std::unique_ptr<SortedDataInterface::Cursor> MobileIndexUnique::newCursor(OperationContext* opCtx,
diff --git a/src/mongo/db/storage/mobile/mobile_index.h b/src/mongo/db/storage/mobile/mobile_index.h
index c7ef60d7061ffe6ce791a83b65c626f5427372b2..69c3ee08bcac918a83fcbdceca586217666c9e19 100644
--- a/src/mongo/db/storage/mobile/mobile_index.h
+++ b/src/mongo/db/storage/mobile/mobile_index.h
@@ -43,7 +43,11 @@ class MobileIndex : public SortedDataInterface {
 public:
     MobileIndex(OperationContext* opCtx, const IndexDescriptor* desc, const std::string& ident);
 
-    MobileIndex(bool isUnique, const Ordering& ordering, const std::string& ident);
+    MobileIndex(bool isUnique,
+                const Ordering& ordering,
+                const std::string& ident,
+                const std::string& collectionNamespace,
+                const std::string& indexName);
 
     virtual ~MobileIndex() {}
 
@@ -135,6 +139,8 @@ protected:
     const Ordering _ordering;
     const KeyString::Version _keyStringVersion = KeyString::kLatestVersion;
     const std::string _ident;
+    const std::string _collectionNamespace;
+    const std::string _indexName;
 };
 
 class MobileIndexStandard final : public MobileIndex {
diff --git a/src/mongo/db/storage/mobile/mobile_index_test.cpp b/src/mongo/db/storage/mobile/mobile_index_test.cpp
index 31419df65fb7255352abfa9f5fbdd6fb9e85250f..4a2502509e28d781c29dfa7c76278193cad491e7 100644
--- a/src/mongo/db/storage/mobile/mobile_index_test.cpp
+++ b/src/mongo/db/storage/mobile/mobile_index_test.cpp
@@ -60,9 +60,10 @@ public:
         fassert(37052, status);
 
         if (isUnique) {
-            return stdx::make_unique<MobileIndexUnique>(_ordering, ident);
+            return stdx::make_unique<MobileIndexUnique>(
+                _ordering, ident, "test.mobile", "indexName");
         }
-        return stdx::make_unique<MobileIndexStandard>(_ordering, ident);
+        return stdx::make_unique<MobileIndexStandard>(_ordering, ident, "test.mobile", "indexName");
     }
 
     std::unique_ptr<RecoveryUnit> newRecoveryUnit() {
diff --git a/src/mongo/db/storage/sorted_data_interface.h b/src/mongo/db/storage/sorted_data_interface.h
index 74355bc96f97a512566c05592d10d0f233ef86bf..4b720468344d3c50448cd0c2e4a89e1cfcb579c8 100644
--- a/src/mongo/db/storage/sorted_data_interface.h
+++ b/src/mongo/db/storage/sorted_data_interface.h
@@ -51,6 +51,20 @@ struct ValidateResults;
  */
 enum SpecialFormatInserted { NoSpecialFormatInserted = 0, LongTypeBitsInserted = 1 };
 
+/**
+ * Returns the formatted error status about the duplicate key.
+ */
+inline Status dupKeyError(const BSONObj& key,
+                          const std::string& collectionNamespace,
+                          const std::string& indexName) {
+    StringBuilder sb;
+    sb << "E11000 duplicate key error";
+    sb << " collection: " << collectionNamespace;
+    sb << " index: " << indexName;
+    sb << " dup key: " << key;
+    return Status(ErrorCodes::DuplicateKey, sb.str());
+}
+
 /**
  * This is the uniform interface for storing indexes and supporting point queries as well as range
  * queries. The actual implementation is up to the storage engine. All the storage engines must
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
index 8043c206ebe480f189c052ea49861d6c1eb51ea3..f260ffe13e0c63c4a9b175f4cdd08a2fce462563 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
@@ -114,15 +114,6 @@ const int kDataFormatV4KeyStringV1UniqueIndexVersionV2 = 12;
 const int kMinimumIndexVersion = kDataFormatV1KeyStringV0IndexVersionV1;
 const int kMaximumIndexVersion = kDataFormatV4KeyStringV1UniqueIndexVersionV2;
 
-Status WiredTigerIndex::dupKeyError(const BSONObj& key) {
-    StringBuilder sb;
-    sb << "E11000 duplicate key error";
-    sb << " collection: " << _collectionNamespace;
-    sb << " index: " << _indexName;
-    sb << " dup key: " << key;
-    return Status(ErrorCodes::DuplicateKey, sb.str());
-}
-
 void WiredTigerIndex::setKey(WT_CURSOR* cursor, const WT_ITEM* item) {
     if (_prefix == KVPrefix::kNotPrefixed) {
         cursor->set_key(cursor, item);
@@ -422,7 +413,7 @@ Status WiredTigerIndex::dupKeyCheck(OperationContext* opCtx,
     WT_CURSOR* c = curwrap.get();
 
     if (isDup(opCtx, c, key, id))
-        return dupKeyError(key);
+        return dupKeyError(key, _collectionNamespace, _indexName);
     return Status::OK();
 }
 
@@ -690,7 +681,7 @@ private:
         if (cmp == 0) {
             // Duplicate found!
             if (!_dupsAllowed) {
-                return _idx->dupKeyError(newKey);
+                return dupKeyError(newKey, _idx->collectionNamespace(), _idx->indexName());
             }
         } else {
             // _previousKey.isEmpty() is only true on the first call to addKey().
@@ -737,7 +728,7 @@ private:
         } else {
             // Dup found!
             if (!_dupsAllowed) {
-                return _idx->dupKeyError(newKey);
+                return dupKeyError(newKey, _idx->collectionNamespace(), _idx->indexName());
             }
 
             // If we get here, we are in the weird mode where dups are allowed on a unique
@@ -1406,7 +1397,7 @@ StatusWith<SpecialFormatInserted> WiredTigerIndexUnique::_insertTimestampUnsafe(
     }
 
     if (!dupsAllowed)
-        return dupKeyError(key);
+        return dupKeyError(key, _collectionNamespace, _indexName);
 
     if (!insertedId) {
         // This id is higher than all currently in the index for this key
@@ -1452,7 +1443,7 @@ StatusWith<SpecialFormatInserted> WiredTigerIndexUnique::_insertTimestampSafe(
         // An entry with prefix key already exists. This can happen only during rolling upgrade when
         // both timestamp unsafe and timestamp safe index format keys could be present.
         if (ret == WT_DUPLICATE_KEY) {
-            return dupKeyError(key);
+            return dupKeyError(key, _collectionNamespace, _indexName);
         }
         invariantWTOK(ret);
 
@@ -1465,7 +1456,7 @@ StatusWith<SpecialFormatInserted> WiredTigerIndexUnique::_insertTimestampSafe(
 
         // Second phase looks up for existence of key to avoid insertion of duplicate key
         if (isDup(opCtx, c, key, id))
-            return dupKeyError(key);
+            return dupKeyError(key, _collectionNamespace, _indexName);
     }
 
     // Now create the table key/value, the actual data record.
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_index.h b/src/mongo/db/storage/wiredtiger/wiredtiger_index.h
index 2b5e1ba3e074f427451661da94ac4537e70faa9d..47f8aff0bb38ab33d5f2ec88a591f83c0db42231 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_index.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_index.h
@@ -155,8 +155,6 @@ public:
     virtual bool unique() const = 0;
     virtual bool isTimestampSafeUniqueIdx() const = 0;
 
-    Status dupKeyError(const BSONObj& key);
-
 protected:
     virtual StatusWith<SpecialFormatInserted> _insert(OperationContext* opCtx,
                                                       WT_CURSOR* c,