Troubleshooting¶
Common errors, solutions, and FAQ.
Common Errors¶
Lock Timeout¶
Another process holds the migration lock. Solutions:
- Wait for the other process to finish.
- Increase timeout:
queen up --timeout 60morConfig{LockTimeout: 60 * time.Minute}. - Check for stuck locks:
SELECT * FROM pg_locks WHERE locktype = 'advisory'(PostgreSQL). - Force unlock (dangerous): Restart the process holding the lock.
Checksum Mismatch¶
Migration file was modified after being applied. This is dangerous in production.
- Development: Reset and re-apply:
queen reset --yes && queen up. - Production: Revert the code change to match the originally applied migration.
Version Conflict¶
Two migrations registered with the same version. Use unique versions for each migration.
Invalid Migration¶
Migration is missing required fields. Every migration needs Version, Name, and at least one of UpSQL or UpFunc.
Invalid Migration Name¶
Migration name must contain only lowercase letters, digits, and underscores. No spaces, hyphens, or uppercase.
Name Too Long¶
Migration names are limited to 63 characters. Use a shorter, more concise name.
No Rollback Defined¶
Migration missing DownSQL or DownFunc. Add the rollback definition.
Migration Failed¶
Error: migration 003 (add_posts) failed during up operation on postgres: syntax error at or near "CREAT"
SQL syntax error. Fix the migration SQL and re-run. The failed migration was not recorded, so queen up will retry it.
Connection Refused¶
Database is not running or connection string is wrong. Verify:
- Database service is running.
- Host, port, and credentials are correct.
- Firewall allows the connection.
Database Locked (SQLite)¶
Another process is writing. Solutions:
- Enable WAL mode:
PRAGMA journal_mode = WAL. - Set busy timeout:
PRAGMA busy_timeout = 5000. - Ensure single writer:
db.SetMaxOpenConns(1).
FAQ¶
Can I modify an applied migration?¶
No. Applied migrations should never be modified. Queen tracks checksums and will detect the change. Create a new migration instead.
How do I skip a migration?¶
Add it to .queenignore:
Can I use Queen with an existing database?¶
Yes. The queen baseline command creates a baseline migration from the current schema. Note that this command is still under development — use queen baseline --dry-run to preview what it would do.
Alternatively, you can manually register existing migrations and use queen gap fill --mark-applied to record them without executing SQL.
How do I import from Goose?¶
Can I run migrations from CLI with Go functions?¶
No. Go functions only work when using Queen as a library. The CLI can only execute SQL migrations.
How do I handle multiple databases?¶
Create separate Queen instances:
What happens if a migration fails halfway?¶
Each migration runs in a transaction (where supported). A failed migration is rolled back, and execution stops. Previously applied migrations remain. Fix the issue and re-run.
How do I test migrations?¶
Use the mock driver or a temporary test database:
func TestMigrations(t *testing.T) {
driver := mock.New()
q := queen.NewTest(t, driver)
q.MustAdd(queen.M{
Version: "001",
Name: "create_users",
UpSQL: `CREATE TABLE users (id INT)`,
DownSQL: `DROP TABLE users`,
})
q.TestUpDown() // Test up then down
q.TestRollback() // Full cycle: up, down one-by-one, up again
}
How do I run migrations in CI/CD?¶
queen check --ci # Validate (exit code 4 on gaps, 5 on pending)
queen up --yes # Apply without prompts
What's the difference between queen down and queen reset?¶
queen downrolls back a specific number of migrations (default: 1).queen resetrolls back all migrations.
Performance¶
Slow Migrations¶
- Profile long-running migrations:
queen log --with-duration. - Use
CREATE INDEX CONCURRENTLY(PostgreSQL) for large tables. - Split large data migrations into batches.
- Add NOT NULL columns in three steps (add nullable, populate, add constraint).
Lock Contention¶
- Increase lock timeout for long migrations.
- Use
Config{SkipLock: true}in single-user development. - Avoid running migrations during peak traffic.