golang-migrate/migrate · error

unable to parse file %v

Error message

unable to parse file %v

What it means

Raised by the Google Cloud Storage driver's loadMigrations when an object's filename parses as a migration but its version number duplicates one already appended (Append returns false). Filenames that fail source.DefaultParse are skipped silently; the error only fires for duplicate versions among parseable object names.

Source

Thrown at source/google_cloud_storage/storage.go:61

		return nil, err
	}
	return &driver, nil
}

func (g *gcs) loadMigrations() error {
	iter := g.bucket.Objects(context.Background(), &storage.Query{
		Prefix:    g.prefix,
		Delimiter: "/",
	})
	object, err := iter.Next()
	for ; err == nil; object, err = iter.Next() {
		_, fileName := path.Split(object.Name)
		m, parseErr := source.DefaultParse(fileName)
		if parseErr != nil {
			continue
		}
		if !g.migrations.Append(m) {
			return fmt.Errorf("unable to parse file %v", object.Name)
		}
	}
	if err != iterator.Done {
		return err
	}
	return nil
}

func (g *gcs) Close() error {
	return nil
}

func (g *gcs) First() (uint, error) {
	v, ok := g.migrations.First()
	if !ok {
		return 0, os.ErrNotExist
	}
	return v, nil

View on GitHub (pinned to 01a9643f14)

Solutions

  1. gsutil ls gs://bucket/prefix and identify filenames with duplicate version numbers
  2. Rename or delete duplicate/backup objects so each version is unique
  3. Re-upload the cleaned migration set and re-run the migration tool

Example fix

// before (bucket objects)
migrations/002_create_users.sql
migrations/002_create_users(1).sql
// after — delete the duplicate upload
migrations/002_create_users.sql
Defensive patterns

Strategy: validation

Validate before calling

it := client.Bucket(bucket).Objects(ctx, &storage.Query{Prefix: prefix})
seen := map[uint]string{}
for {
    obj, err := it.Next()
    if err == iterator.Done { break }
    if err != nil { return err }
    m, perr := source.DefaultParse(path.Base(obj.Name))
    if perr != nil { continue }
    if prev, dup := seen[m.Version]; dup {
        return fmt.Errorf("duplicate version %d: %s vs %s", m.Version, prev, obj.Name)
    }
    seen[m.Version] = obj.Name
}

Try / catch

if err := loadMigrations(ctx); err != nil {
    if strings.HasPrefix(err.Error(), "unable to parse file") {
        return fmt.Errorf("duplicate migration versions in GCS bucket: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: loadMigrations (invoked from Open and from tests) iterating a GCS bucket where two objects resolve to the same migration version.

Common situations: Bucket containing backup copies of migrations (e.g. uploaded twice, or with timestamps in metadata), merged branches both adding migration NNN, or objects copied between environments with colliding version numbers.

Understand the failure class

Related errors


AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02). Data as JSON: /api/errors/cde00d3d1286dfa1. Report an issue: GitHub.