{"record":{"id":"e72ebd3dcd5baec9","repo":"golang-migrate/migrate","slug":"max-retries-exceeded","errorCode":null,"errorMessage":"max retries exceeded","messagePattern":"max retries exceeded","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"database/yugabytedb/yugabytedb.go","lineNumber":33,"sourceCode":"\t\"github.com/golang-migrate/migrate/v4\"\n\t\"github.com/golang-migrate/migrate/v4/database\"\n\t\"github.com/jackc/pgconn\"\n\t\"github.com/jackc/pgerrcode\"\n\t\"github.com/lib/pq\"\n)\n\nconst (\n\tDefaultMaxRetryInterval    = time.Second * 15\n\tDefaultMaxRetryElapsedTime = time.Second * 30\n\tDefaultMaxRetries          = 10\n\tDefaultMigrationsTable     = \"migrations\"\n\tDefaultLockTable           = \"migrations_locks\"\n)\n\nvar (\n\tErrNilConfig          = errors.New(\"no config\")\n\tErrNoDatabaseName     = errors.New(\"no database name\")\n\tErrMaxRetriesExceeded = errors.New(\"max retries exceeded\")\n)\n\nfunc init() {\n\tdb := YugabyteDB{}\n\tdatabase.Register(\"yugabyte\", &db)\n\tdatabase.Register(\"yugabytedb\", &db)\n\tdatabase.Register(\"ysql\", &db)\n}\n\ntype Config struct {\n\tMigrationsTable     string\n\tLockTable           string\n\tForceLock           bool\n\tDatabaseName        string\n\tMaxRetryInterval    time.Duration\n\tMaxRetryElapsedTime time.Duration\n\tMaxRetries          int\n}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/database/yugabytedb/yugabytedb.go#L15-L51","documentation":"The yugabytedb driver returns ErrMaxRetriesExceeded ('max retries exceeded') after its bounded retry loop (DefaultMaxRetries = 10) fails to perform a locked operation on the migrations/lock tables, typically while acquiring the advisory/table lock or ensuring the schema_migrations table exists. It signals repeated transient failures (connections, contention) rather than a single bad request.","triggerScenarios":"Retries exhausted while ensuring the migrations table or acquiring the lock table row in YugabyteDB; unstable connectivity to the cluster; very slow DDL/lock operations in YB so every attempt times out.","commonSituations":"Migrating against a YugabyteDB cluster under load or during tablet rebalancing; network flakiness between CI and the cluster; long-running migrations holding the lock table; running many concurrent migrate processes.","solutions":["Verify connectivity to the cluster and that the database/table exist and are reachable before retrying.","Run migrations again once the cluster is healthy — the error is retryable by design.","Check for concurrent migrate processes holding the lock table; ensure previous migrations released the lock.","Increase retry headroom by tuning the driver's retry config if supported, or run migrations during a quieter window.","Inspect YB server logs/tablet issues if the error recurs consistently."],"exampleFix":"// before\nif err := migrate.Up(); err != nil { log.Fatal(err) }\n// after\nif err := migrate.Up(); err != nil {\n\tif errors.Is(err, yugabytedb.ErrMaxRetriesExceeded) {\n\t\tlog.Println(\"transient lock/table contention, retrying in 30s...\")\n\t\ttime.Sleep(30 * time.Second)\n\t\treturn migrate.Up()\n\t}\n\tlog.Fatal(err)\n}","handlingStrategy":"retry","validationCode":"// pre-check: database reachable and migrations table present\nif _, err := conn.Query(\"SELECT 1\"); err != nil {\n\treturn fmt.Errorf(\"cluster unreachable before migrate: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := migrate.Up(); err != nil {\n\tif errors.Is(err, yugabytedb.ErrMaxRetriesExceeded) {\n\t\t// wait and retry; check for stale locks in the lock table first\n\t}\n}","preventionTips":["Run migrations serially — avoid concurrent migrate processes contending for the lock table","Ensure network stability between CI and the YugabyteDB cluster","Check for stale lock rows in the lock table after crashed runs","Schedule migrations outside peak load / tablet rebalancing windows"],"tags":["go","golang-migrate","yugabytedb","retry","lock-contention"],"backgroundTag":"max-retries-exceeded","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}