MySQL LOAD DATA File Not Found (Errcode: 2): Check INFILE Path
If LOAD DATA or LOAD XML reports “File … not found (Errcode: 2)”, first identify which process must open that path. Without LOCAL, the MySQL server reads the file from the server's filesystem; with LOCAL, the client reads it and sends it to the server. Prove that boundary before moving files, changing permissions, or enabling LOCAL.
First read the failing statement: INFILE means server-side file access; LOCAL INFILE means client-side file access. Then inspect server restrictions and LOCAL capability before moving files or changing permissions.
SELECT @@secure_file_priv, @@local_infile;Interpret: secure_file_priv = directory → server-side files must be there; empty value → this variable imposes no directory restriction; NULL → server-side import/export operations governed by it are disabled. @@local_infile applies to LOCAL capability, but the client must permit LOCAL too.
Why this happens
For server-side file operations, MySQL resolves the file on the database server host. With LOCAL, the client reads the file and sends it to the server. A correct-looking path can therefore point to the wrong machine—or outside a Docker container entirely. MySQL can restrict server-side import/export paths with secure_file_priv. Server-side LOAD DATA also has privilege requirements, but a privilege error is not the same diagnosis as operating-system Errcode 2.
Diagnose before changing more
Without LOCAL, the server must be able to see the file. With LOCAL, the client process must be able to read it.
Directory → server-side file operations are restricted there. Empty value → no directory restriction from this variable. NULL → the governed server-side file operations are disabled.
Use an absolute path and verify spelling, case and permissions on the correct host.
Check the path inside the server/container for non-LOCAL, or inside the actual client process for LOCAL. A file on your desktop does not exist inside a remote server/container unless it is transferred or mounted there.
Do not guess its base directory. Use an absolute path while diagnosing so you can prove exactly which file location is being requested.
Fix #2 — use the correct server or client path
If the statement is server-side, place the file where the server process can see it and, when secure_file_priv names a directory, inside that permitted directory. Use an absolute path while diagnosing. Server-side LOAD DATA requires the relevant server-side file privilege; diagnose that only if MySQL reports a privilege/access error rather than Errcode 2.
If you intentionally need client-side loading, use LOCAL only when both the client and server permit it. In current MySQL 8.4 documentation, LOCAL capability can be disabled on either side; the mysql client can explicitly control it with --local-infile, and restricted local loading can be limited with --load-data-local-dir.
LOAD DATA LOCAL INFILE '/absolute/client/path/file.csv'
INTO TABLE your_table;Verify: Repeat the import with the intended server/client path. Success means MySQL moves past Errcode 2 and begins processing the file.
Fix #3 — interpret secure_file_priv correctly instead of disabling it
If @@secure_file_priv names a directory, move/copy the server-side import file there and ensure the MySQL server process can access it. If it is empty, do not invent a secure_file_priv restriction that is not present. If it is NULL, switching paths will not enable the governed server-side file operation. Avoid weakening the setting globally just to make one import succeed.
SHOW VARIABLES LIKE 'secure_file_priv';Verify: Run the same operation after placing the file in the permitted directory. If the error changes, stop changing paths and diagnose the new message.
Fix #4 — remote server or Docker: verify the path inside the real reader
For non-LOCAL imports, inspect the filesystem from the MySQL server's point of view. If MySQL runs in Docker, a host path such as /home/me/data.csv does not exist in the container unless it is mounted/copied there, and the SQL statement must use the container-side path. For remote MySQL, your workstation path is likewise irrelevant to server-side INFILE.
For LOCAL, reverse the perspective: the relevant path belongs to the client process executing the statement. A GUI, application server, CLI running over SSH, and your laptop may all be different clients.
Verify: prove the file exists at the exact absolute path from the filesystem namespace of the process that must open it, then rerun the same statement.
What not to do
Still seeing the error?
If Errcode 2 remains, compare the exact path MySQL reports with the path visible to the process that must open it, including filename case and container/remote mounts. Only after existence/path ownership is proven should you move to access permissions. If the error code/message changes, stop: the file-not-found problem has likely been passed and the new error deserves its own diagnosis.
Official references
Still stuck? Ask the community
Share your operating system, software version, exact error text, and which fix you already tried. Another reader may have seen the same setup.
Loading community discussion…
Comments could not load here. Open ErrorHarbor Discussions on GitHub →