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, nilView on GitHub (pinned to 01a9643f14)
Solutions
- gsutil ls gs://bucket/prefix and identify filenames with duplicate version numbers
- Rename or delete duplicate/backup objects so each version is unique
- 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
- Keep the bucket path migrations-only; separate prefixes per environment
- CI or deploy-time lint of bucket object names for unique versions
- Avoid manual re-uploads that create duplicate copies
- Use lifecycle rules to clean stale objects
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to parse file %v
- unable to parse file %v
- database is dirty
- database is dirty
- unable to obtain lock
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/cde00d3d1286dfa1.
Report an issue: GitHub.