sethserver.com
A dark green database cylinder with a glowing leaf emblem, secured by a brass padlock whose keyhole is formed from percent signs and at symbols, on a deep charcoal background.

MongoDB Password Generator with URL Encoding

By Seth Black • Updated: September 17, 2026

generating...

Percent-encoded password (for connection strings only)

Create the user in mongosh

Run while connected as a user with the userAdmin or userAdminAnyDatabase role. Uses the raw password, not the encoded one.

Change an existing user's password

Connection string, self-hosted (mongodb://)

Replace localhost:27017 with your host or replica set members.

Connection string, Atlas (mongodb+srv://)

Replace the host with your cluster's. Create the Atlas user in the Atlas UI or CLI with the raw password; Atlas users authenticate against admin.

Every password on this page is generated in your browser with crypto.getRandomValues. Nothing gets sent to my server and nothing is stored. Regenerate as many times as you like, then copy the pieces you need.

I built this because the password itself is never the hard part of a MongoDB user. The hard part is that the same password has to live in three places with three sets of rules: the db.createUser() call, your secrets store, and a connection string that is secretly a URL. Get the URL part wrong and you spend an afternoon staring at "Authentication failed" while the password is, technically, correct.

Why MongoDB passwords break connection strings

A MongoDB connection string is a URI. The username and password sit in the userinfo part, before the @, so any character with a meaning in a URL can change how the driver parses it. The MongoDB manual says that if a username or password includes $ : / ? # [ ] @, those characters must be converted using percent-encoding. The Atlas docs give a longer list: : / ? # [ ] @ ! $ & ' ( ) * , ; = % and the space character.

Two more traps the short list doesn't warn you about:

So the generator uses the boring, safe rule: percent-encode every character except letters, digits and - . _ ~ (the RFC 3986 unreserved set). That is the same output as Python's urllib.parse.quote_plus for these character sets, and both mongosh and PyMongo accept it (I tested both against MongoDB 8 before publishing this).

Here's the part people get backwards. Encode only for the URI. In db.createUser(), db.changeUserPassword(), the Atlas UI, the Atlas CLI, or a mongosh password prompt, use the raw password. If you paste the encoded form into createUser, then %40 is literally part of the password, and your correctly encoded connection string will fail because the driver decodes it back to @.

If you would rather not think about any of this, tick "URL-safe only". You get letters, digits and - . _ ~, the encoded form equals the raw form, and you give up about 0.4 bits per character. At 32 characters that's still around 193 bits, which is plenty.

Turn on access control first

A self-hosted mongod does not require authentication out of the box. Creating users does nothing for you until access control is on. In mongod.conf:

security:
  authorization: enabled

Or start mongod with --auth. Restart it, then connect from the same machine. With authorization enabled and no users yet, MongoDB's localhost exception lets a local connection create the first user, which should be a user administrator:

use admin
db.createUser({
  user: "userAdmin",
  pwd: passwordPrompt(),
  roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})

Once that user exists, the localhost exception closes. Log in as userAdmin and create your application users from there. The official Docker image does the same dance for you when you set MONGO_INITDB_ROOT_USERNAME and MONGO_INITDB_ROOT_PASSWORD, but note that the account it creates has the root role, which brings me to the next point.

Never let your app connect as an admin user

I've inherited more than one project where the application connected as the root user created by the Docker image, because that was the only user anyone had made. It works. It also means a single injection bug, a leaked .env file, or an overly helpful AI coding agent can drop every database on the server.

Give each application its own user, scoped to its own database, with the smallest built-in role that works:

RoleUse it for
readReporting jobs, dashboards, analytics exports
readWriteA normal application: read and write documents, create collections and indexes
dbOwnerA separate migration user, not the app's everyday connection

The db.createUser() command above grants one role on one database. If a service only reads, give it read. If you want the longer argument, I wrote about the principle of least privilege in the AI age, which matters more now that code you didn't write is holding your credentials.

SCRAM-SHA-256

MongoDB's default password mechanism is SCRAM. When you call db.createUser() without a mechanisms field, MongoDB creates credentials for both SCRAM-SHA-1 and SCRAM-SHA-256. The generated command sets mechanisms: [ "SCRAM-SHA-256" ] so the user only gets the SHA-256 credential. Any current driver handles that; if you are stuck with an ancient driver that only speaks SCRAM-SHA-1, delete that line.

SCRAM means the server stores a salted, iterated verifier rather than your password. It does not mean the password travels safely. The MongoDB docs are blunt about this: db.createUser() sends the password to the server in cleartext unless the connection uses TLS, even when you use passwordPrompt(). Turn on TLS if the connection leaves the machine.

Keep passwords out of your shell history

The generated commands include the password inline so you can see exactly what's being set. For real use on a shared server, swap the password for passwordPrompt():

use appdb
db.createUser({
  user: "appUser",
  pwd: passwordPrompt(),
  roles: [ { role: "readWrite", db: "appdb" } ]
})

db.changeUserPassword("appUser", passwordPrompt())

mongosh redacts credentials from its own command history, which is nice, but that doesn't cover the bash history line where you ran mongosh "mongodb://appUser:secret@...", a --eval script, your terminal scrollback, or the screen share you forgot was running. The prompt keeps it off the screen entirely.

Atlas database users versus self-hosted users

On Atlas you do not use db.createUser(). MongoDB's docs say Atlas database users must be managed through the Atlas UI, the Atlas CLI, the Administration API or a supported integration, and Atlas rolls back user changes made any other way. The CLI version looks like this:

atlas dbusers create readWriteAnyDatabase --username appUser --password 'PASTE-RAW-PASSWORD'

Better still, use --role readWrite@appdb instead of readWriteAnyDatabase so the user can only touch one database. Paste the raw password, not the encoded one. In bash, single quotes stop $ and ! from being interpreted, which is one more reason the generator leaves single quotes out of the character set.

The other Atlas difference is the authentication database. Password users on Atlas authenticate against admin. A self-hosted user authenticates against whichever database you ran use on when you created it. The driver picks the authentication database in this order: authSource, then the database in the URI path, then admin. That's why the self-hosted template says authSource=appdb and the Atlas one says authSource=admin, even though both name appdb in the path.

One Atlas detail on mongodb+srv://: you give one host and no port, and the +srv form turns TLS on by default.

Rotating a MongoDB password without downtime

A MongoDB user has one password at a time. db.changeUserPassword() replaces it immediately, and every client still using the old one fails its next authentication. For a single app with a short restart, that's fine: change the password, update the secret, restart.

For anything where a failed login is an outage, rotate by user instead of by password:

  1. Create appUser_v2 with the same role and a fresh password from this page.
  2. Deploy the new connection string everywhere.
  3. Watch the logs until nothing authenticates as appUser.
  4. Drop the old user with db.dropUser("appUser").

Generate a MongoDB password offline

If your policy says secrets are generated on your own machine, these all use the operating system's CSPRNG. Hex and base64url output never needs percent-encoding, which is a nice side effect.

# 64 hex characters, 256 bits
openssl rand -hex 32

# 43 URL-safe characters, 256 bits
python3 -c "import secrets; print(secrets.token_urlsafe(32))"

# same thing in Node
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"

# percent-encode an existing password for a URI
python3 -c "import sys, urllib.parse; print(urllib.parse.quote_plus(sys.argv[1]))" 'your-password'

Avoid openssl rand -base64 for MongoDB unless you remember to encode it: standard base64 contains +, / and =, and the + is exactly the one PyMongo turns into a space.

Common mistakes

A strong password is honestly the easy part of all this. My book Databases in the Era of AI puts it as "secrets are the easy 10%, insecure data flow is the rest," and the rest is where apps actually get hurt.

MongoDB password FAQ

Which characters need percent-encoding in a MongoDB connection string?

The MongoDB manual lists $ : / ? # [ ] @ as characters that must be percent-encoded in the username or password of a connection string. The Atlas documentation adds ! & ' ( ) * , ; = % and the space character. The percent sign itself always needs encoding, and a plus sign should be encoded as %2B because PyMongo decodes a bare + as a space. Encoding everything except letters, digits and - . _ ~ is the safe rule, and it is what this generator does.

Do I percent-encode the password in db.createUser() too?

No. Percent-encoding only belongs inside a mongodb:// or mongodb+srv:// URI. In db.createUser(), db.changeUserPassword(), the Atlas UI, the Atlas CLI and the mongosh password prompt, use the raw password. If you create the user with the encoded form, the encoded string becomes the real password and your connection string will fail to authenticate.

Why does my connection string say Authentication failed when the password is right?

The usual causes are an unencoded special character, the wrong authentication database, or a + that the driver turned into a space. MongoDB authenticates against the authSource option, then the database in the URI path, then admin. A user created with use appdb needs authSource=appdb, while Atlas database users live in admin, so an Atlas URI that names a database in the path should also say authSource=admin.

How long should a MongoDB password be?

Nobody types an application password, so make it long. This generator defaults to 32 characters, which is about 207 bits from the full character set or about 193 bits from the URL-safe set. Anything past roughly 128 bits is already out of reach of guessing, so pick whichever character set causes you the least escaping pain.

Can I create Atlas database users with db.createUser()?

No. MongoDB documents that Atlas database users must be managed through the Atlas UI, the Atlas CLI, the Atlas Administration API or a supported integration, and Atlas rolls back user changes made any other way. Use atlas dbusers create or the Database Access page instead, and paste the raw password there.

Is this MongoDB password generator safe to use?

The password is generated in your browser with crypto.getRandomValues and never leaves the page. Nothing is sent to my server or stored. That said, you are trusting this page and your browser, so if your policy says secrets must come from your own machine, use one of the offline commands on this page instead.

Related tools: Redis Password Generator, SQL Server Password Generator, MySQL Password Generator, PostgreSQL Password Generator, and the general strong password generator.

-Sethers

Newsletter

One email, once a week.

Notes on databases, systems, and the occasional strong opinion about Python. No spam, unsubscribe anytime.

More to read

All tools →

My Password Generators Had 53 Bits of Entropy

Sep 21, 2026

API Key Generator with Prefix, Checksum and SHA-256

Sep 17, 2026

Bcrypt Generator: Hash and Verify Passwords in Your Browser

Sep 17, 2026