golang-migrate/migrate · error
both x-advisory-lock-timeout-interval and x-advisory-lock-ti
Error message
both x-advisory-lock-timeout-interval and x-advisory-lock-timout-interval were specified
What it means
ErrLockTimeoutConfigConflict is returned by mongodb.Open when the connection URL contains both the canonical x-advisory-lock-timeout-interval parameter and the misspelled legacy alias x-advisory-lock-timout-interval. The driver refuses to guess which timeout to use, so Open fails fast. Using only one of the two is accepted (the typo is kept for backwards compatibility).
Source
Thrown at database/mongodb/mongodb.go:41
db := Mongo{}
database.Register("mongodb", &db)
database.Register("mongodb+srv", &db)
}
var DefaultMigrationsCollection = "schema_migrations"
const DefaultLockingCollection = "migrate_advisory_lock" // the collection to use for advisory locking by default.
const lockKeyUniqueValue = 0 // the unique value to lock on. If multiple clients try to insert the same key, it will fail (locked).
const DefaultLockTimeout = 15 // the default maximum time to wait for a lock to be released.
const DefaultLockTimeoutInterval = 10 // the default maximum intervals time for the locking timout.
const DefaultAdvisoryLockingFlag = true // the default value for the advisory locking feature flag. Default is true.
const LockIndexName = "lock_unique_key" // the name of the index which adds unique constraint to the locking_key field.
const contextWaitTimeout = 5 * time.Second // how long to wait for the request to mongo to block/wait for.
var (
ErrNoDatabaseName = fmt.Errorf("no database name")
ErrNilConfig = fmt.Errorf("no config")
ErrLockTimeoutConfigConflict = fmt.Errorf("both x-advisory-lock-timeout-interval and x-advisory-lock-timout-interval were specified")
)
type Mongo struct {
client *mongo.Client
db *mongo.Database
config *Config
isLocked atomic.Bool
}
type Locking struct {
CollectionName string
Timeout int
Enabled bool
Interval int
}
type Config struct {
DatabaseName string
MigrationsCollection stringView on GitHub (pinned to 01a9643f14)
Solutions
- Remove the misspelled x-advisory-lock-timout-interval parameter from the URL
- Keep only x-advisory-lock-timeout-interval (the correctly spelled key)
- Audit all DSN sources (env, config files, secrets) for duplicate lock-timeout keys
Example fix
// before mongodb://localhost:27017/mydb?x-advisory-lock-timeout-interval=30&x-advisory-lock-timout-interval=30 // after mongodb://localhost:27017/mydb?x-advisory-lock-timeout-interval=30
Defensive patterns
Strategy: validation
Validate before calling
u, _ := url.Parse(dsn)
q := u.Query()
if q.Get("x-advisory-lock-timeout-interval") != "" && q.Get("x-advisory-lock-timout-interval") != "" {
return fmt.Errorf("remove duplicate/misspelled x-advisory-lock-timout-interval from DSN")
} Try / catch
if err != nil {
if errors.Is(err, mongodb.ErrLockTimeoutConfigConflict) {
return fmt.Errorf("DSN specifies lock timeout twice (typo key still present)")
}
return err
} Prevention
- Standardize on x-advisory-lock-timeout-interval in all environments
- Grep config/secrets repos for the misspelled x-advisory-lock-timout-interval
- Keep the canonical DSN in one templated source, not per-env copies
When it happens
Trigger: A MongoDB DSN with both x-advisory-lock-timeout-interval and x-advisory-lock-timout-interval query parameters, e.g. after someone 'fixed' part of the name while an old copy still contained the typo.
Common situations: Merging config from two sources (env var + config file) where one predates the spelling fix; copy-pasting DSNs from old documentation that used the misspelled key.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- no database name
- no config
- invalid value for x-migrations-table: %w
- invalid value for x-connect-insecure: %w
- no config
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/5fb087ce8da73e92.
Report an issue: GitHub.