golang-migrate/migrate · error
source driver: unknown driver '%s' (forgotten import?)
Error message
source driver: unknown driver '%s' (forgotten import?)
What it means
Raised by source.Open when the URL scheme is valid but no driver is registered under that scheme. Drivers self-register via init() when their package is imported, so this almost always means the driver package was never imported (blank import) or the scheme is misspelled.
Source
Thrown at source/driver.go:90
ReadDown(version uint) (r io.ReadCloser, identifier string, err error)
}
// Open returns a new driver instance.
func Open(url string) (Driver, error) {
u, err := nurl.Parse(url)
if err != nil {
return nil, err
}
if u.Scheme == "" {
return nil, fmt.Errorf("source driver: invalid URL scheme")
}
driversMu.RLock()
d, ok := drivers[u.Scheme]
driversMu.RUnlock()
if !ok {
return nil, fmt.Errorf("source driver: unknown driver '%s' (forgotten import?)", u.Scheme)
}
return d.Open(url)
}
// Register globally registers a driver.
func Register(name string, driver Driver) {
driversMu.Lock()
defer driversMu.Unlock()
if driver == nil {
panic("Register driver is nil")
}
if _, dup := drivers[name]; dup {
panic("Register called twice for driver " + name)
}
drivers[name] = driver
}
View on GitHub (pinned to 01a9643f14)
Solutions
- Add a blank import for the driver: _ "github.com/golang-migrate/migrate/v4/source/github" (matching the scheme)
- Check the scheme spelling in the URL against the registered driver name
- If using the CLI, ensure it was built with the required driver (or use a build that includes it)
Example fix
// before
import (
"github.com/golang-migrate/migrate/v4"
)
// after
import (
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/source/github"
) Defensive patterns
Strategy: validation
Validate before calling
import (
_ "github.com/golang-migrate/migrate/v4/source/github"
_ "github.com/golang-migrate/migrate/v4/source/gitlab"
)
// then, before Open:
known := []string{"github", "gitlab", "file", "s3"}
scheme := parsed.Scheme
if !slices.Contains(known, scheme) {
return fmt.Errorf("unsupported source scheme %q", scheme)
} Type guard
func driverRegistered(scheme string) bool {
_, err := source.Open(scheme + "://probe")
return !strings.Contains(err.Error(), "unknown driver")
} Try / catch
d, err := source.Open(srcURL)
if err != nil {
if strings.Contains(err.Error(), "unknown driver") {
return fmt.Errorf("forgot blank import for source driver in %q? %w", srcURL, err)
}
return err
} Prevention
- Blank-import every source/database driver you use in each binary
- Keep the import list in a single drivers.go file per service
- Match URL scheme exactly to the name passed to source.Register
When it happens
Trigger: source.Open('githubs://...') (typo), or using a driver like 'github://', 's3://' or 'gitlab://' without importing _ 'github.com/golang-migrate/migrate/v4/source/github' (etc.) in the binary.
Common situations: Building a custom binary that uses migrate programmatically and forgetting the blank import; renaming schemes between versions; CLI users hitting a build of the tool that excludes that driver.
Related errors
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/d46e8df7b79ef65e.
Report an issue: GitHub.