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

  1. Register the exact file path with mysql.RegisterLocalFile(filepath) before executing the LOAD DATA statement.
  2. If you fully trust the server, add allowAllFiles=true to the DSN to permit any local file (less secure).
  3. Ensure the path string in the SQL matches the registered path exactly, including quotes and trailing characters.
  4. 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

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


AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04). Data as JSON: /data/errors/fb3b1badbd3fe997.json. Report an issue: GitHub.