RocketChat/Rocket.Chat · warning
Not migrating, control is locked. Will retry.
Error message
Not migrating, control is locked. Will retry.
What it means
Database migrations are guarded by a lock in the control document so only one instance migrates at a time. This warning means lock() failed — another instance holds the lock, or a crashed instance left control.locked=true. The server sleeps retryInterval (10s) and retries recursively, up to maxAttempts (30, ~5 minutes), after which it halts with 'ERROR! SERVER STOPPED — Database migration control is locked'.
Solutions
- Do nothing if another instance is legitimately migrating — this instance retries every 10s and proceeds once the lock releases
- If no other instance is running, clear the stale lock: in MongoDB set the migrations control document's locked=false (back up the database first)
- For rolling deployments, let the first instance finish booting before starting the rest
- If the server stops after ~30 attempts, inspect what holds the lock (another live instance? Mongo health?) and restart after resolving
Example fix
// mongo shell, only when no instance is migrating
// before
db.rocketchat_migrations.findOne() // { locked: true, version: 355, ... }
// after
db.rocketchat_migrations.updateOne({}, { $set: { locked: false } }) Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight before starting an instance that will migrate
const control = db.collection('rocketchat_migrations').findOne();
if (control?.locked) {
// find out who holds the lock; only clear it after confirming no instance is migrating
logger.warn(`Migration lock held (version ${control.version}); waiting instead of forcing`);
} Prevention
- Deploy sequentially: let the first instance complete migrations before scaling up
- Never kill a server mid-migration; if it dies, verify and clear control.locked manually with a DB backup
- Keep MongoDB healthy (replica set, no step-downs) during migration windows
- Expect up to 30 retries × 10s before the server halts — treat repeated warnings as an operator alert, not noise
When it happens
Trigger: Booting multiple Rocket.Chat instances against the same database at a new version simultaneously (scale-up, k8s rollout, docker-compose scale); a previous migration that crashed mid-run leaving locked=true; an instance stuck mid-migration on a slow or unhealthy MongoDB.
Common situations: Rolling deployments where all replicas start at once; a server killed during migration (OOM, restart) so the lock was never released; dev and prod pointing at the same DB; replica set step-down during migration.
Related errors
- Error dropping redundant indexes, continuing...
- Invalid MONGO_OPTIONS environment variable: must be valid…
- Invalid settings found on DB. Deleting them.
- App already exists.
- App could not be enabled
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/186c8692026e6db4.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/server/lib/migrations.ts:190
}
// version 0 means it is a fresh database, just set the control to latest known version and skip
if (currentVersion === 0) {
await setControl({
locked: false,
version: orderedMigrations[orderedMigrations.length - 1].version,
});
return true;
}
const version = targetVersion === 'latest' ? orderedMigrations[orderedMigrations.length - 1].version : targetVersion;
// get latest version
// const { version } = orderedMigrations[orderedMigrations.length - 1];
if (!(await lock())) {
if (currentAttempt <= maxAttempts) {
log.warn({
msg: 'Not migrating, control is locked. Will retry.',
retryIntervalSeconds: retryInterval,
attempt: currentAttempt,
maxAttempts,
});
await sleep(retryInterval * 1000);
currentAttempt++;
return migrateDatabase(targetVersion, subcommands);
}
const control = await getControl(); // Side effect: upserts control document.
showErrorBox(
'ERROR! SERVER STOPPED',
[
'Your database migration control is locked.',
'Please make sure you are running the latest version and try again.',
'If the problem persists, please contact support.',View on GitHub (pinned to b2c16d5842)