Appearance
MongoDB
Section: 13 — Data
Last Updated: 2026-05-30
Scope: MongoDB VM setup, Cosmos DB production, SCRAM gotcha, intentional typo
CRITICAL: The Intentional MonogoDb Typo
CAUTION
DO NOT "fix" the MonogoDb typo. It is intentional and load-bearing.
The NuGet package Microtec.Persistence reads the connection string from the key MonogoDb__ConnectionString — note the transposed o and g: MonogoDb, not MongoDB.
This typo exists in:
- All
appsettings.jsonfiles across every microservice - All environment variable declarations in Docker Compose and ACA
- Azure Key Vault secrets (double-dash format:
MonogoDb--ConnectionString) - Pipeline variable groups
- The NuGet package source code itself
Why It Can't Be Fixed
Fixing this would require:
- Publishing a new major version of
Microtec.Persistence(or affected package) - Updating every consuming service's
appsettings.json - Updating all ACA environment variable configs
- Updating all Key Vault secrets
- Coordinated deployment across all environments
Risk vs reward: The typo is harmless — treat it as a known quirk and document it.
Where the Typo Appears
json
// appsettings.json (ALL services that use MongoDB)
{
"MonogoDb": {
"ConnectionString": "mongodb://...",
"DatabaseName": "microtec"
}
}yaml
# Docker Compose / ACA environment variables
- name: MonogoDb__ConnectionString
value: "mongodb://..."
- name: MonogoDb__DatabaseName
value: "microtec"# Azure Key Vault secret name (double-dash convention)
MonogoDb--ConnectionString
MonogoDb--DatabaseNameTIP
When onboarding a new microservice that needs MongoDB, always spell it MonogoDb in config. Search the codebase for MonogoDb (not MongoDB) when debugging connection issues.
VM-Based MongoDB (Non-Production)
Infrastructure Overview
| Property | Value |
|---|---|
| Engine | MongoDB 7.0 Community |
| Environments | Development, Stage, Pre-Production |
| Deployment | Docker containers on VM |
| Ports | 27017–27020 (replica set or standalone per env) |
| Auth | SCRAM-SHA-256 (see gotcha below) |
Port Allocation
| Port | Environment |
|---|---|
| 27017 | Development |
| 27018 | Stage |
| 27019 | Pre-Production |
| 27020 | Reserved / UAT |
Docker Compose Example
yaml
services:
mongodb-dev:
image: mongo:7.0
container_name: mic-mongodb-dev
ports:
- "27017:27017"
environment:
# DO NOT use MONGO_INITDB_ROOT_* — see SCRAM gotcha below
MONGO_INITDB_DATABASE: microtec
volumes:
- mongodb_dev_data:/data/db
- ./mongo-init:/docker-entrypoint-initdb.d
networks:
- mic-networkCRITICAL: MongoDB Init SCRAM Gotcha
CAUTION
Using MONGO_INITDB_ROOT_USERNAME / MONGO_INITDB_ROOT_PASSWORD environment variables creates a broken SCRAM authentication setup.
The Problem
When MongoDB 7.0 initializes via the MONGO_INITDB_ROOT_* environment variables, it creates the root user with only SCRAM-SHA-1. However, the .NET MongoDB driver (v2.x+) negotiates SCRAM-SHA-256 by default. The result: the container starts successfully but every application connection attempt fails with an authentication error that looks like a password mismatch.
MongoAuthenticationException: Unable to authenticate using sasl protocol mechanism SCRAM-SHA-256Workaround: db.updateUser() via Noauth Container
The fix is to start MongoDB without authentication, create the user properly (with both SCRAM mechanisms), then restart with auth enabled.
Step 1: Start without auth to create/update the user:
yaml
# init-service (runs once, exits)
services:
mongodb-init:
image: mongo:7.0
command: >
mongosh --host mongodb-dev --eval "
db = db.getSiblingDB('admin');
db.createUser({
user: 'admin',
pwd: '${MONGO_PASSWORD}',
roles: [{ role: 'root', db: 'admin' }],
mechanisms: ['SCRAM-SHA-1', 'SCRAM-SHA-256']
});
db.getSiblingDB('microtec').createUser({
user: 'microtec_user',
pwd: '${MONGO_APP_PASSWORD}',
roles: [{ role: 'readWrite', db: 'microtec' }],
mechanisms: ['SCRAM-SHA-1', 'SCRAM-SHA-256']
});
"
depends_on:
- mongodb-dev-noauthStep 2: If user already exists with broken SCRAM, update via noauth:
javascript
// Connect to mongo WITHOUT auth (--noauth flag or security.authorization: disabled)
db = db.getSiblingDB('admin');
db.updateUser(
"admin",
{
mechanisms: ["SCRAM-SHA-1", "SCRAM-SHA-256"],
pwd: "your_password_here"
}
);Step 3: Restart with --auth (or security.authorization: enabled).
Why This Happens
MongoDB 7.0 changed its default SCRAM mechanism handling. The MONGO_INITDB_ROOT_* env var path was not updated to specify both mechanisms, so it only creates the legacy SCRAM-SHA-1 credential. The .NET driver prefers SCRAM-SHA-256 and does not automatically fall back.
Production: Azure Cosmos DB (Mongo API)
Why Cosmos DB in Production
| Requirement | How Cosmos DB Meets It |
|---|---|
| 99.999% SLA | Multi-region writes |
| Managed backups | Continuous 7-day backup |
| Global distribution | Multi-region replica reads |
| No ops overhead | Fully managed PaaS |
| MongoDB wire protocol | Mongo API compatibility |
NOTE
Cosmos DB for MongoDB does not support 100% of MongoDB 7.0 features. Aggregation pipeline operators and some index types may differ. Test all MongoDB queries against Cosmos DB emulator in CI.
Cosmos DB Configuration
json
{
"MonogoDb": {
"ConnectionString": "mongodb://<account>:<key>@<account>.mongo.cosmos.azure.com:10255/?ssl=true&retrywrites=false&maxIdleTimeMS=120000&appName=@<account>@",
"DatabaseName": "microtec"
}
}Key differences from standard MongoDB connection string:
- Port
10255(not 27017) ssl=truerequiredretrywrites=falserequired (Cosmos DB does not support retryable writes in all tiers)maxIdleTimeMS=120000prevents stale connections
Key Vault Secret (Production)
Secret name: MonogoDb--ConnectionString
Secret value: mongodb://<account>:<key>@<account>.mongo.cosmos.azure.com:10255/...Connection String Reference
| Environment | Format | Notes |
|---|---|---|
| Local dev | mongodb://localhost:27017 | No auth |
| Dev/Stage/Preprod | mongodb://user:pass@host:port/db?authSource=admin | VM-based |
| Production | mongodb://...:...@*.mongo.cosmos.azure.com:10255/?ssl=true&... | Cosmos DB |
Troubleshooting
Auth Failures
bash
# Check if user has correct SCRAM mechanisms
mongosh --host <host> --port <port> --eval \
"db.getSiblingDB('admin').system.users.findOne({user:'admin'}, {mechanisms:1})"
# Expected output:
# { mechanisms: ['SCRAM-SHA-1', 'SCRAM-SHA-256'] }
# If only SCRAM-SHA-1 → run the updateUser workaround aboveConnection String Typo Debugging
bash
# Grep for the correct (typo) key name
grep -r "MonogoDb" . --include="appsettings*.json"
# If you find "MongoDB" (without typo) somewhere, that config will be IGNORED
grep -r "MongoDB__ConnectionString\|MongoDB--ConnectionString" .Cosmos DB Throttling
Response status code does not indicate success: TooManyRequests (429)Increase RU/s or add retry policy:
csharp
var settings = MongoClientSettings.FromConnectionString(connectionString);
settings.RetryWrites = false;
settings.MaxConnectionIdleTime = TimeSpan.FromMinutes(2);