ERROR 1030 (HY000): Got error <errno> from storage engine is raised when the storage engine (typically InnoDB) returns an OS-level or internal error code that MySQL cannot map to a more specific error message. The error symbol is ER_GET_ERRNO.
The number embedded in the message — for example Got error 28 from storage engine — is an OS errno or an InnoDB internal code, not a MySQL error code. That number is the real diagnostic signal.
Impact
Any DML or DDL statement that triggers storage engine I/O can surface this error: SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, ALTER TABLE, and index operations are all candidates. The affected statement is rolled back; other connections are not affected unless the underlying condition is systemic (e.g., a full disk or a corrupted tablespace).
In application code the error surfaces as a database exception with error number 1030. ORMs like Hibernate, SQLAlchemy, ActiveRecord, and Sequelize will propagate it as a generic driver exception. Because the message text includes a numeric errno that varies by situation, string-matching the error message in application code is fragile — catch by error number instead.
Common Causes
Disk full (errno 28 — ENOSPC). The filesystem hosting the MySQL data directory has no free space. This is the single most frequent cause of error 1030 in production. InnoDB cannot extend a tablespace file or write to the redo log.
Corrupted InnoDB tablespace or index (errno 1 or internal codes like 122, 126, 140, 141). An
.ibdfile or the system tablespace has been damaged — typically by a hard shutdown, storage failure, or filesystem error.File permission issues (errno 13 — EACCES). The MySQL process user (
mysql) lacks read/write permission on a tablespace file or the data directory, often after a manual file operation or OS upgrade.Too many open files (errno 24 — EMFILE). The process has hit the OS
open fileslimit (ulimit -n). InnoDB opens one file per table wheninnodb_file_per_table=ON.Table marked crashed (MyISAM). MyISAM tables can be flagged as crashed after an unclean shutdown, triggering errno 145 (
ER_TABLE_CORRUPT).InnoDB redo log or doublewrite buffer errors. Incomplete recovery after a crash can leave InnoDB in a state where it refuses to write, returning internal storage engine codes.
Troubleshooting and Resolution Steps
Read the errno from the error message. The number after "Got error" is the key. Check the MySQL error log for context around the same timestamp:
SHOW GLOBAL VARIABLES LIKE 'log_error';Then inspect the file at that path on the server.
For errno 28 — check disk space.
df -h /var/lib/mysqlFree space by removing unused binary logs (if
expire_logs_days/binlog_expire_logs_secondsis not set), purging application-level data, or expanding the volume. After freeing space, retry the failed statement. InnoDB will resume normally — no restart is needed unless the redo log was corrupted mid-write.-- Safe way to reclaim binary log space SHOW BINARY LOGS; PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;For errno 13 — fix file permissions.
ls -la /var/lib/mysql/<database>/ chown -R mysql:mysql /var/lib/mysql/ chmod 660 /var/lib/mysql/<database>/<table>.ibdFor errno 24 — raise the open files limit.
Check current usage and the limit:
cat /proc/$(pidof mysqld)/limits | grep 'open files'Raise it in
/etc/security/limits.confor the MySQL systemd unit, then restart MySQL. Inmy.cnfyou can also set:[mysqld] open_files_limit = 65535For a corrupted InnoDB table — attempt repair via dump and restore.
InnoDB does not support
REPAIR TABLE. The standard recovery path is:-- Force InnoDB to skip the corrupted page and allow reads SET GLOBAL innodb_force_recovery = 1; -- increase to 6 only as last resortWith recovery mode active, dump the table:
mysqldump --single-transaction mydb bad_table > bad_table.sqlThen drop and reimport:
DROP TABLE bad_table; SOURCE bad_table.sql;Reset
innodb_force_recoveryto 0 and restart.For a crashed MyISAM table.
CHECK TABLE my_table; REPAIR TABLE my_table;Or from the shell:
mysqlcheck --repair mydb my_table -u root -p
Additional Information
- The SQLSTATE
HY000is a generic "general error" class — it does not encode the specific sub-cause, so always inspect the errno in the message text and the error log. - Error 1030 is a wrapper; the underlying errno comes from the OS or InnoDB's internal error table. Common OS errnos: 1 (EPERM), 13 (EACCES), 24 (EMFILE), 28 (ENOSPC), 30 (EROFS — read-only filesystem).
- In cloud environments (RDS, Aurora, Cloud SQL), disk-full conditions may surface differently — Aurora auto-expands storage, but RDS does not by default. Check the
FreeStorageSpaceCloudWatch metric. - Related errors:
1005 (ER_CANT_CREATE_TABLE)for table creation failures,1016 (ER_CANT_OPEN_FILE)for file open failures, and1034 (ER_OLD_KEYFILE)for MyISAM index corruption. innodb_force_recoverylevels above 3 prevent InnoDB from writing — only use them temporarily for data extraction, never for normal operation.
Frequently Asked Questions
What does "Got error 28" mean specifically?
Errno 28 is the POSIX ENOSPC error — "No space left on device." InnoDB could not write to the data directory because the filesystem is full. Check disk usage with df -h and free space before doing anything else.
Can I run REPAIR TABLE on InnoDB to fix this?
No. REPAIR TABLE only works with MyISAM, ARCHIVE, and CSV storage engines. For InnoDB corruption, use innodb_force_recovery to export the data, then drop and recreate the table from the dump.
The error only appears under load — what should I check?
Intermittent 1030 errors under load often point to hitting the open_files_limit (errno 24) or a race condition on a nearly-full disk. Check SHOW GLOBAL STATUS LIKE 'Opened_files' and compare it against SHOW VARIABLES LIKE 'open_files_limit'. Also monitor disk usage trends — a disk that is 95% full can trigger sporadic failures.
Why doesn't MySQL give a clearer error message?
Error 1030 is a boundary between MySQL's SQL layer and the pluggable storage engine API. The storage engine reports an OS or internal code that MySQL maps back to the generic ER_GET_ERRNO message. The real diagnostic information is always in the errno value and the MySQL error log.