The server failed to close an internal file handle, indicating exhausted file descriptors or an OS-level file system issue.
MySQL Error 30 (EE_FILE_NOT_CLOSED) occurs when the server cannot close a file handle, often because the operating system has run out of available file descriptors. Check open_files_limit, run FLUSH TABLES, and raise system ulimit values to resolve the issue.
File '%s' (fileno: %d) was not closed
The message signals that MySQL attempted to close a file but the close() system call failed. The operating system still considers the descriptor open, so MySQL logs error code 30 (EE_FILE_NOT_CLOSED).
This is a low-level file handling failure.
It usually points to resource exhaustion, kernel limits, or a bug that leaked file descriptors inside the MySQL process.
Error 30 most often appears during heavy write activity, log rotation, large SELECT INTO OUTFILE jobs, or after long-running sessions that open many temporary tables.
It can also occur during backup and restore operations that touch hundreds of files.
Open descriptor leaks stack up until MySQL can no longer open new tables or redo logs. Queries begin failing with unrelated errors, replication can stop, and data loss is possible after a crash. Prompt mitigation maintains stability and prevents downtime.
See common causes below.
Follow the step-by-step solutions in the Fixes section.
Typical remedies include increasing open_files_limit, flushing tables, and restarting the server. Galaxy users can run these SQL commands directly in the editor and share the fix script with teammates.
Heavy OLTP workloads, test environments with low ulimit values, Docker containers without adjusted fs.file-max, and long-lived ETL scripts are frequent culprits.
Each scenario maps to one of the fixes shown later.
Monitor open_files with Performance Schema, keep open_files_limit 20–30 percent above peak, and schedule periodic FLUSH TABLES. Galaxy’s editor lets teams store these maintenance queries in a shared Collection for reuse.
Errors such as ER_FILE_NOT_FOUND, ER_CANT_OPEN_FILE, ER_DISK_FULL, and ER_OUT_OF_RESOURCES stem from similar file system limits. Their fixes overlap with the techniques described for EE_FILE_NOT_CLOSED.
.
ulimit -n or kernel fs.file-max is lower than MySQL’s open_files_limit, causing failures when the server closes a handle.
Long-running sessions that create many internal temporary tables may not release them promptly, leaving descriptors open.
External scripts moving or truncating log files while MySQL is writing can interrupt close() operations.
Docker or Kubernetes pods often start with 1024 or 4096 descriptors, far below production needs, triggering the error under load.
Underlying disk faults or NFS glitches can prevent the kernel from closing a file cleanly, surfacing as EE_FILE_NOT_CLOSED.
.
Issue FLUSH TABLES to release handles, then check open_files_limit and OS descriptor limits. If the error persists, plan an orderly restart.
No. If you can free enough descriptors with FLUSH TABLES and raise limits dynamically, a restart may be skipped. Persistent leaks usually need a restart.
Set the value at least 20-30 percent above the peak shown in Open_files status. Production systems often use 100000 or more.
Yes. Save diagnostic queries in a Galaxy Collection, share them with teammates, and let the AI copilot suggest optimized FLUSH/SET commands on the spot.