go-sql-driver/mysql · error
local file '%s' is not registered
Error message
local file '%s' is not registered
What it means
Thrown during a 'LOAD DATA LOCAL INFILE' operation: the MySQL server asked the driver to send a local file (infile.go:141), but that path is neither in the driver's allowlist (registered via mysql.RegisterLocalFile) nor covered by the allowAllFiles=true DSN option. The driver deliberately refuses to send arbitrary files to prevent a rogue server from exfiltrating sensitive data. Only explicitly allowlisted paths are readable.
Source
Thrown at infile.go:141
_, exists := fileRegister[name]
fileRegisterLock.RUnlock()
if mc.cfg.AllowAllFiles || exists {
var file *os.File
var fi os.FileInfo
if file, err = os.Open(name); err == nil {
defer deferredClose(&err, file)
// get file size
if fi, err = file.Stat(); err == nil {
rdr = file
if fileSize := int(fi.Size()); fileSize < packetSize {
packetSize = fileSize
}
}
}
} else {
err = fmt.Errorf("local file '%s' is not registered", name)
}
}
// send content packets
var data []byte
// if packetSize == 0, the Reader contains no data
if err == nil && packetSize > 0 {
data = make([]byte, 4+packetSize)
var n int
for err == nil {
n, err = rdr.Read(data[4:])
if n > 0 {
if ioErr := mc.conn().writePacket(data[:4+n]); ioErr != nil {
return ioErr
}
}
}View on GitHub (pinned to c426bd9379)
Solutions
- Register the exact file path with mysql.RegisterLocalFile(filepath) before executing the LOAD DATA statement.
- If you fully trust the server, add allowAllFiles=true to the DSN to permit any local file (less secure).
- Ensure the path string in the SQL matches the registered path exactly, including quotes and trailing characters.
- For in-memory/dynamic data, use mysql.RegisterReaderHandler("name", fn) and reference 'Reader::name' in the SQL.
Example fix
// before
err := db.Exec("LOAD DATA LOCAL INFILE '/data/sales.csv' INTO TABLE sales")
// after
mysql.RegisterLocalFile("/data/sales.csv")
err := db.Exec("LOAD DATA LOCAL INFILE '/data/sales.csv' INTO TABLE sales") Defensive patterns
Strategy: validation
Validate before calling
// register the exact path before issuing LOAD DATA LOCAL INFILE
filePath := "/data/sales.csv"
mysql.RegisterLocalFile(filePath)
// only then:
db.Exec("LOAD DATA LOCAL INFILE '" + filePath + "' INTO TABLE sales") Try / catch
res, err := db.Exec("LOAD DATA LOCAL INFILE '/data/sales.csv' INTO TABLE sales")
if err != nil {
if strings.Contains(err.Error(), "is not registered") {
// path not allowlisted: register it or enable allowAllFiles=true in the DSN
}
} Prevention
- Register each file path with mysql.RegisterLocalFile before referencing it in SQL.
- Keep the registered path and the SQL path string byte-for-byte identical.
- Prefer the explicit allowlist over allowAllFiles=true for least privilege.
When it happens
Trigger: Calling db.Exec("LOAD DATA LOCAL INFILE '/data/sales.csv' INTO TABLE sales") without first calling mysql.RegisterLocalFile("/data/sales.csv") and without allowAllFiles=true in the DSN. The server requests the file by name; the driver looks it up in fileRegister (infile.go:123) and rejects it.
Common situations: Forgetting to register the file before the query; the path in the SQL string differs from the registered path (relative vs absolute, trailing slash, quoting); migrating away from allowAllFiles=true toward least privilege; the server echoes back an absolute path that does not match the registered one.
Related errors
- invalid DSN: interpolateParams can not be used with unsafe c
- invalid bool value: {value}
- TLS requested but server does not support TLS
- this user requires clear text authentication. If you still w
- this user requires old password authentication. If you still
AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04).
Data as JSON: /data/errors/fb3b1badbd3fe997.json.
Report an issue: GitHub.