gofr-dev/gofr · error
failed to record migration: %w
Error message
failed to record migration: %w
What it means
Thrown when IndexDocument fails while persisting a migration record (document ID = migration number for idempotency) into the gofr_migrations index during commitMigration. The migration itself ran, but its record could not be written, so subsequent runs may re-execute it. The wrapped error holds the actual ES failure.
Source
Thrown at pkg/gofr/migration/elasticsearch.go:164
return em.migrator.beginTransaction(c)
}
// commitMigration records the migration in the tracking index.
func (em elasticsearchMigrator) commitMigration(c *container.Container, data transactionData) error {
if data.UsedDatasources[dsElasticsearch] {
migrationDoc := map[string]any{
"version": data.MigrationNumber,
"method": "UP",
"start_time": data.StartTime.Format(time.RFC3339),
"duration": time.Since(data.StartTime).Milliseconds(),
}
// Use the migration number as the document ID for idempotency
docID := fmt.Sprintf("%d", data.MigrationNumber)
err := c.Elasticsearch.IndexDocument(context.Background(), elasticsearchMigrationIndex, docID, migrationDoc)
if err != nil {
return fmt.Errorf("failed to record migration: %w", err)
}
c.Debugf("Inserted record for migration %v in Elasticsearch gofr_migrations index", data.MigrationNumber)
}
return em.migrator.commitMigration(c, data)
}
// rollback is a no-op for Elasticsearch migrations.
func (em elasticsearchMigrator) rollback(c *container.Container, data transactionData) {
em.migrator.rollback(c, data)
c.Fatalf("Migration %v failed.", data.MigrationNumber)
}
func (em elasticsearchMigrator) lock(ctx context.Context, cancel context.CancelFunc, c *container.Container, ownerID string) error {
return em.migrator.lock(ctx, cancel, c, ownerID)
}
View on GitHub (pinned to 187eb24962)
Solutions
- Check the wrapped ES error for the specific cause (mapping/permissions/cluster state)
- Ensure the gofr_migrations index allows writes and has a compatible mapping
- Restore ES availability, then re-run the migration — doc ID idempotency makes it safe
- Clear disk-watermark read-only blocks if the index is read-only
Example fix
// before
// commit fails: failed to record migration: version_conflict_engine_exception
// after
// verify doc for this migration number isn't already applied, then retry commit
_, err := c.Elasticsearch.GetDocument(ctx, "gofr_migrations", fmt.Sprintf("%d", data.MigrationNumber))
if err != nil { return em.commitMigration(c, data) } // idempotent retry Defensive patterns
Strategy: retry
Validate before calling
// pre-check write access
if err := c.Elasticsearch.IndexDocument(ctx, "gofr_migrations", "_healthcheck", map[string]string{"ping":"1"}); err != nil {
return fmt.Errorf("gofr_migrations index not writable: %w", err)
} Try / catch
err := migrator.Run(c)
if err != nil && strings.Contains(err.Error(), "failed to record migration") {
// document ID is idempotent: safe to retry with backoff
time.Sleep(2 * time.Second)
err = migrator.Run(c)
} Prevention
- Validate index mapping compatibility before upgrading gofr versions
- Monitor disk usage to avoid disk-watermark read-only blocks
- Use credentials with write access to gofr_migrations
- Rely on doc-ID idempotency to make retries safe
When it happens
Trigger: c.Elasticsearch.IndexDocument() returns an error for the migration doc: ES down, mapping conflict on the index, document too large, write/403 permission, or version conflict on the same doc ID.
Common situations: Index created earlier with an incompatible mapping; read-only cluster due to disk watermark; network blip mid-migration; ES credentials lacking write access.
Related errors
- elasticsearch: %w
- invalid elasticsearch response
- error encoding operation
- %w: settings: %w
- %w: creating index: %w
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/9261d3512a029cef.
Report an issue: GitHub.