Skip to content
MongoDB

MongoDB Error 48

NamespaceExists: collection already exists

Applies to: MongoDB 7.0 and 8.0 (wordings checked against the 8.0 source)
Last technically reviewed 24 October 2026 on MongoDB 8.0 documentation and source (error_codes.yml r8.0.0); not run locally
The full message
MongoServerError: namespace shop.events already exists, but with different options: { validator: { ... } }
Other forms of this message
Creating a collection inside a multi-document transaction
Collection shop.events already exists.
From the catalogue check (for example inside a transaction) when the name is a view or a time series collection
A view already exists. NS: shop.events
A timeseries collection already exists. NS: shop.events
Creating a view whose name exists as a view on another source
namespace shop.events_v already exists, but is a view on shop.events rather than shop.events_2025
renameCollection onto an existing collection (replica set or standalone)
target namespace exists
renameCollection onto the name of a view
a view already exists with that name: shop.events_v
renameCollection on a sharded cluster
Target collection shop.events_old exists but dropTarget is not set
Error code
48
Code name
NamespaceExists
Product
MongoDB
Versions
MongoDB 7.0 and 8.0 (wordings checked against the 8.0 source)
Last reviewed
24 October 2026

What it means

Error 48 (NamespaceExists) means a create or rename targets a database.collection name that is already taken, by a collection with different options, a view or a time series collection, so MongoDB refused to replace it.

In MongoDB 8.0 creating a collection that already exists with the same options is not an error: outside a transaction, the create command compares the requested options with the existing collection's and returns success when they match. You get 48 when they do not match, and the message shows the existing collection's options after but with different options:, so you can see what differs (for example a validator, capped settings or a collation). Inside a multi-document transaction the server returns the plain Collection ... already exists. form instead, because the error aborts the transaction.

A name can also be taken by something that is not an ordinary collection: a view, or a time series collection, which the messages name explicitly. For renames, renameCollection refuses to overwrite an existing target unless you pass dropTarget: true, and the documentation shows the operation failing when the target name is an existing collection.

The usual setting is a migration or start-up script that runs on every deploy. If it creates collections with options (validators, time series, collation), the second run fails as soon as anyone has changed those options, by hand or through collMod.

Common causes

  • A start-up or migration script calls createCollection with options that differ from those of the existing collection.
  • The collection was created implicitly (by an insert or createIndex) with default options, and a later explicit createCollection adds a validator or other options.
  • A view or time series collection already uses the name.
  • renameCollection targets a name that is already in use, without dropTarget.
  • createCollection runs inside a transaction for a collection that already exists.

Diagnose it

Read-only These mongosh commands only read data, indexes, statistics and server state (find, aggregate without $out or $merge, getIndexes, stats, currentOp, rs.status). They do not change data, users or settings, so they are safe to run first.

What is already there, and with which options?

db.getCollectionInfos({ name: "events" })
What to look for

One entry with type (collection, view or timeseries) and options. Compare those options with the ones your script passes.

Is the rename target free?

db.getCollectionNames().filter(n => n === "events_old")
What to look for

An empty array means the target name is free; a match means the rename needs a different target or dropTarget.

How many documents would a dropTarget rename discard?

db.events_old.estimatedDocumentCount()
What to look for

The approximate size of the existing target. Anything above zero is data that dropTarget: true would delete.

How to fix it

Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.

Change the options with collMod instead of re-creating

Changes schema

When the collection exists and only its validator or validation settings should change, modify it in place. This keeps the data and indexes.

db.runCommand({
  collMod: "events",
  validator: { $jsonSchema: { bsonType: "object", required: [ "type", "at" ] } },
  validationLevel: "moderate"
})

Create only when the collection is missing

Changes schema

Make set-up scripts idempotent: check for the name first, create with options only when it is absent, and apply option changes through collMod.

if (!db.getCollectionNames().includes("events")) {
  db.createCollection("events", { validator: { $jsonSchema: { bsonType: "object" } } })
}

Rename to a free name

Changes schema

Pick a target that does not exist, such as a dated archive name, rather than overwriting.

db.events.renameCollection("events_archive_2026_10")

Overwrite the target deliberately (dropTarget)

Changes data

Only when the existing target really should be replaced: the second argument of renameCollection is dropTarget.

Caution: dropTarget deletes the existing target collection and its indexes before the rename. Back it up or rename it out of the way first, and check its size with the read-only count above.

db.events_new.renameCollection("events", true)

Examples

Adding a validator by re-creating the collection

Not reproduced here: no MongoDB server is installed for this site. The text is built by checkCollectionOptions() in MongoDB 8.0's create_command.cpp; the part after "different options:" is the existing collection's options document, shortened here. Running the same createCollection with identical options would succeed.

db.events.insertOne({ type: "click" })      // creates events with default options

db.createCollection("events", {
  validator: { $jsonSchema: { bsonType: "object", required: [ "type" ] } }
})
Expected result (documented format, not run)
MongoServerError: namespace shop.events already exists, but with different options: { ... }

Renaming onto an existing collection

Not reproduced here: no MongoDB server is installed for this site. The text is the fixed string in MongoDB 8.0's rename_collection.cpp for a rename within one database on a replica set or standalone server; on a sharded cluster the check runs in the sharding rename code (sharding_ddl_util.cpp) and can use the dropTarget wording shown in the variants.

db.events_new.renameCollection("events")
Expected result (documented format, not run)
MongoServerError: target namespace exists

How to prevent it

Create collections that need options in one migration step that runs once, and change options later with collMod, never by calling createCollection again with new options.

In application start-up code, either skip explicit creation or check getCollectionInfos() first, and treat code 48 as a signal to compare options rather than as something to ignore.

Common questions

Does createCollection fail if the collection already exists?

In MongoDB 8.0, outside a transaction, not when the options are identical: the command succeeds. It returns 48 when the options differ, when the name is a view or time series collection, or inside a transaction.

How do I add a validator to an existing collection?

Use collMod with the validator (and optionally validationLevel and validationAction) instead of createCollection. The data and indexes stay as they are.

How do I rename a collection over an existing one?

Pass dropTarget: true (the second argument of renameCollection), which deletes the existing target first. Back it up before you do.

Official documentation

Last technically reviewed 24 October 2026; examples and diagnostics run on MongoDB 8.0 documentation and source (error_codes.yml r8.0.0); not run locally. Codes and code names are checked against MongoDB's error_codes.yml (8.0); no MongoDB server was available, so the examples were not run locally.

Still stuck on a MongoDB error?

Browse the full MongoDB error library, or get hands-on help from an experienced SQL professional.