The 2 AM Log PanicYou just deployed a sleek real-time notification feature. On paper, everything looked perfect. But the moment your service hits the database, your logs explode with this error:
MongoServerError: The $changeStream stage is only supported on replica sets or sharded clusters
This happens because your local environment or test server is likely running a standalone MongoDB instance. Standalone instances are the default for many installers, but they lack an Oplog (Operations Log). Since Change Streams rely entirely on the Oplog to broadcast data events, they simply won't work without it.
The Quick Fix (TL;DR)You must convert your standalone MongoDB into a single-node replica set. Even if you never plan to add a second server, MongoDB requires the replication machinery to be active to enable Change Streams. This process usually takes less than 60 seconds.
- Restart your
mongodprocess with the--replSetflag:mongod --replSet rs0- Openmongoshand run:rs.initiate()## Why This HappensStandard installations on macOS (Homebrew), Windows, or Ubuntu start MongoDB as a single, isolated process. This saves about 5% of disk space by skipping Oplog creation. However, Change Streams work by "tailing" the Oplog. No Oplog? No streams. By turning on replication, you tell MongoDB to start recording every write operation to a hidden collection, which the Change Stream then watches.
Fixing Local InstallationsIf you aren't using Docker and installed MongoDB directly on your machine, follow these steps.
1. Update your configurationOpen your mongod.conf file. If you used Homebrew on an Apple Silicon Mac, itβs usually at /opt/homebrew/etc/mongod.conf. On Linux, check /etc/mongod.conf. Add these two lines:
replication:
replSetName: "rs0"
2. Restart the databaseApply the new configuration by restarting the service.
# For macOS users
brew services restart mongodb-community
# For Linux users
sudo systemctl restart mongod
3. Activate the Replica SetEnter the MongoDB shell by typing mongosh. Run the initiation command:
rs.initiate()
Give it 3 to 5 seconds. Your command prompt will change from test> to rs0 [direct: primary] test>. You are now running a single-node replica set.
Fixing Docker Compose EnvironmentsStandard Docker images like mongo:latest start in standalone mode. To fix this in your development workflow, use a docker-compose.yml setup that handles the initialization automatically. This avoids the manual rs.initiate() step every time you wipe your volumes.
services:
mongo:
image: mongo:6.0
command: ["--replSet", "rs0", "--bind_ip_all"]
ports:
- "27017:27017"
healthcheck:
test: "mongosh --eval 'rs.initiate()' || exit 0"
interval: 10s
timeout: 5s
retries: 5
Note the || exit 0 in the healthcheck. This prevents the container from reporting an error if rs.initiate() is called on a database that is already initialized.
Confirming the FixTesting the fix is straightforward. Create a file named watch.js and paste this Node.js snippet:
const { MongoClient } = require('mongodb');
async function run() {
const uri = 'mongodb://localhost:27017/?replicaSet=rs0';
const client = new MongoClient(uri);
await client.connect();
console.log('Connected. Watching testdb.orders...');
const stream = client.db('testdb').collection('orders').watch();
stream.on('change', (change) => {
console.log('Event detected:', change.operationType, change.fullDocument);
});
}
run().catch(console.error);
Run node watch.js. Insert a document into the orders collection using your GUI or shell. If the event appears in your terminal, the error is officially resolved.

