How to fix EE_FILENOTFOUND (29): File not found in MySQL

MySQLINTERMEDIATEMEDIUMUpdated Dec 22, 2025· 140 views

MySQL error 29 (EE_FILENOTFOUND) occurs when the database server cannot locate a required file. This commonly happens with LOAD DATA INFILE operations, when accessing database table files, or due to file permission restrictions.

Quick fix

Fixes 29

# On Linux/Mac
ls -la /path/to/your/file.csv

# On Windows
dir C:\path\to\your\file.csv
  1. Verify the file exists and check the full path
  2. Add LOCAL keyword for client-side files
  3. Enable local_infile if using LOCAL keyword
  4. Check secure-file-priv restrictions
mysql — error
# On Linux/Mac
ls -la /path/to/your/file.csv
# On Windows
dir C:\path\to\your\file.csv
EE_FILENOTFOUND (29): File not found

What this error means

Error 29 is MySQL's generic "file not found" error, represented by the symbol EE_FILENOTFOUND. The full error message format is "File '%s' not found (OS errno %d - %s)", which includes the filename and the underlying operating system error code. This error indicates that MySQL attempted to access a file but failed to locate it. The file could be a data file you're trying to import (LOAD DATA INFILE), a database table file (.MYD, .MYI, .frm), or a configuration file. The specific OS errno included in the error message provides additional context about why the operating system couldn't find the file—common codes include errno 2 (file doesn't exist) and errno 13 (permission denied). Unlike permission-only errors, EE_FILENOTFOUND encompasses multiple scenarios: the file genuinely doesn't exist at the specified path, MySQL is looking in the wrong directory, security configurations prevent access, or file system permissions block MySQL from seeing the file.

Typical symptoms

  • LOAD DATA INFILE commands fail with "File not found" message
  • Error occurs even when the file exists at the specified path
  • Database operations fail with references to missing .MYD or .MYI files
  • Import operations work with absolute paths but fail with relative paths
  • Error includes OS errno codes like 2 (not found) or 13 (permission denied)
  • Docker container mount operations fail when trying to use existing databases

Common causes

  1. File path is incorrect or relative path resolves to wrong directory
  2. LOCAL keyword missing from LOAD DATA LOCAL INFILE for client-side files
  3. local_infile system variable is disabled in MySQL configuration
  4. File located outside secure-file-priv directory when that setting is enabled
  5. Insufficient file system permissions preventing MySQL from reading the file
  6. AppArmor or SELinux security policies blocking MySQL file access (Linux)
  7. Database table files moved or deleted while server is running
  8. Backslashes in Windows file paths not properly escaped or converted

How to fix "EE_FILENOTFOUND (29): File not found"

1Verify the file exists and check the full path

First, confirm the file actually exists at the location you specified:

bash
# On Linux/Mac
ls -la /path/to/your/file.csv

# On Windows
dir C:\path\to\your\file.csv

For LOAD DATA operations, use an absolute path instead of a relative path to eliminate ambiguity:

sql
-- Use absolute path
LOAD DATA INFILE '/var/lib/mysql-files/data.csv'
INTO TABLE your_table
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n';

On Windows, use forward slashes or escaped backslashes:

sql
-- Forward slashes (recommended)
LOAD DATA INFILE 'C:/data/file.csv'
INTO TABLE your_table;

-- Or escaped backslashes
LOAD DATA INFILE 'C:\\data\\file.csv'
INTO TABLE your_table;
2Add LOCAL keyword for client-side files

If your file is on the client machine (not the MySQL server), you must use LOAD DATA LOCAL INFILE:

sql
-- For files on your local machine
LOAD DATA LOCAL INFILE '/home/user/data.csv'
INTO TABLE your_table
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;

Without LOCAL, MySQL expects the file to be on the database server host. With LOCAL, the MySQL client reads the file and sends it to the server.

3Enable local_infile if using LOCAL keyword

The local_infile setting controls whether LOAD DATA LOCAL INFILE is allowed. Check if it's enabled:

sql
SHOW GLOBAL VARIABLES LIKE 'local_infile';

If it shows OFF, enable it:

sql
SET GLOBAL local_infile = 1;

To make this permanent, add to your MySQL configuration file:

ini
# In /etc/mysql/my.cnf or /etc/my.cnf (Linux)
# Or C:\ProgramData\MySQL\MySQL Server 8.0\my.ini (Windows)
[mysqld]
local-infile=1

[mysql]
local-infile=1

After editing the config file, restart MySQL:

bash
# Linux (systemd)
sudo systemctl restart mysql

# Linux (older systems)
sudo service mysql restart

# Windows
net stop MySQL80
net start MySQL80

MySQL Workbench: Edit your connection, go to the Advanced tab, and add OPT_LOCAL_INFILE=1 in the "Others:" box.

4Check secure-file-priv restrictions

MySQL's secure-file-priv setting restricts file operations to a specific directory. Check the current setting:

sql
SHOW VARIABLES LIKE 'secure_file_priv';

Possible values:
- A directory path: You can only load files from this directory
- Empty string: No restrictions (not recommended for production)
- NULL: File operations are completely disabled

If a directory is set, move your file there:

bash
# Common secure-file-priv directories
# Linux: /var/lib/mysql-files/
# Windows: C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\

sudo cp /path/to/data.csv /var/lib/mysql-files/
sudo chown mysql:mysql /var/lib/mysql-files/data.csv

To change the secure-file-priv directory (requires restart), edit your my.cnf:

ini
[mysqld]
secure-file-priv = "/path/to/your/data/directory"

Note: Setting secure-file-priv = "" disables restrictions but creates security risks.

5Fix file permissions

MySQL must have read access to the file. Set appropriate permissions:

bash
# Make file readable by MySQL
sudo chmod 644 /path/to/file.csv

# Make directory accessible
sudo chmod 755 /path/to/directory

# Change ownership to mysql user (if needed)
sudo chown mysql:mysql /path/to/file.csv

Verify permissions:

bash
ls -la /path/to/file.csv
# Should show: -rw-r--r-- mysql mysql

On Windows, right-click the file → Properties → Security tab, and ensure the MySQL service account has Read permissions.

6Configure AppArmor (Linux/Ubuntu)

If you're on Ubuntu or Debian, AppArmor may be blocking MySQL file access even when permissions are correct. Check AppArmor status:

bash
sudo aa-status | grep mysql

To allow MySQL to access your directory, edit the local AppArmor profile:

bash
sudo nano /etc/apparmor.d/local/usr.sbin.mysqld

Add your directory (replace with your actual path):

bash
/path/to/your/data/** r,

Reload the AppArmor profile:

bash
sudo systemctl reload apparmor
# Or
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld

Temporary testing: Switch MySQL to complain mode (logs violations but doesn't block):

bash
sudo aa-complain /usr/sbin/mysqld

If this fixes the issue, AppArmor was the problem. Switch back to enforce mode after updating the profile:

bash
sudo aa-enforce /usr/sbin/mysqld

Advanced notes

SELinux Considerations: On Red Hat/CentOS/Fedora systems with SELinux enabled, similar restrictions apply. Check SELinux context:

bash
ls -Z /path/to/file.csv

Set the correct context:

bash
sudo semanage fcontext -a -t mysqld_db_t "/path/to/data(/.*)?"
sudo restorecon -Rv /path/to/data

Database File Recovery: If the error references missing .MYD or .MYI files, your database tables may be corrupted. Try repairing:

sql
REPAIR TABLE your_table;
CHECK TABLE your_table;

For MyISAM tables with completely missing files, you may need to restore from backups.

Docker Considerations: When mounting existing database directories in Docker, ensure the volume mount is correct and the MySQL user (UID 999 by default) has access:

bash
sudo chown -R 999:999 /path/to/mysql/data

Symbolic Links: If using symlinks for database directories or data files, MySQL must be configured to follow them with the symbolic-links=1 option, though this is disabled by default for security reasons.

FILE Privilege: For non-LOCAL LOAD DATA operations, your MySQL user needs the FILE privilege:

sql
GRANT FILE ON *.* TO 'your_user'@'localhost';
FLUSH PRIVILEGES;

However, FILE is a sensitive privilege that allows reading any file the MySQL server can access. Grant it carefully.

Frequently asked questions

What does "29" mean?
Error 29 is MySQL's generic "file not found" error, represented by the symbol EE_FILENOTFOUND. The full error message format is "File '%s' not found (OS errno %d - %s)", which includes the filename and the underlying operating system error code. This error indicates that MySQL attempted to access a file but failed to locate it.
How do I fix "29"?
MySQL error 29 (EE_FILENOTFOUND) occurs when the database server cannot locate a required file. This commonly happens with LOAD DATA INFILE operations, when accessing database table files, or due to file permission restrictions.
What causes "29"?
File path is incorrect or relative path resolves to wrong directory LOCAL keyword missing from LOAD DATA LOCAL INFILE for client-side files local_infile system variable is disabled in MySQL configuration
Is the "29" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading