MySQL Error Code Lookup: Causes and Fixes
Paste a MySQL error number such as 1064, a full line like ERROR 1045 (28000): Access denied for user, a symbol such as ER_DUP_ENTRY, a SQLSTATE, or just the message your application logged, and this tool identifies the error, explains why MySQL raised it and gives a concrete fix with the SQL or configuration to change. It covers the most searched server errors (1000-1999 and the newer 3000+ codes) and client errors (2000-2999) such as 2002 and 2006, notes where MariaDB differs, and generates ready-to-paste handlers for Python, Java, Node.js, Go and PHP. Everything runs in your browser; nothing you paste is sent anywhere.
Do more than mysql error code lookup: causes and fixes — meet Chat2DB
Chat2DB is an AI-powered SQL client for Windows, macOS and Linux. Write SQL in natural language, format and optimize queries automatically, and manage MySQL, PostgreSQL, Oracle and 20+ other databases in one workspace.
MySQL error codes reference (85 common errors)
Every MySQL error has three identifiers: a numeric error code (the errno, e.g. 1062), a symbol (ER_DUP_ENTRY for server errors, CR_ for client-library errors) and a five-character SQLSTATE (23000). The number is the most precise - many different errors share one SQLSTATE such as HY000 or 23000 - so application code should branch on the number. MariaDB shares the 1000–1999 numbering for most classic errors listed here, but diverges for newer codes: the 3000+ errors below are MySQL-only, and MariaDB assigns its own meanings to codes in the 1900s and 4000s. Click any number to load it into the tool above.
Server errors 1000–1999 (classic)
Raised by mysqld and sent to the client. This numbering is shared by MariaDB for almost all of these classic errors.
| Error | Symbol | SQLSTATE | Meaning |
|---|---|---|---|
| ER_CANT_CREATE_TABLE | HY000 | CREATE/ALTER TABLE failed (often errno 150: bad foreign key). | |
| ER_DB_CREATE_EXISTS | HY000 | Database already exists. | |
| ER_DB_DROP_EXISTS | HY000 | Database to drop does not exist. | |
| ER_DUP_KEY | 23000 | Duplicate key while writing (often duplicate FK name). | |
| ER_OPEN_AS_READONLY | HY000 | Table is read only. | |
| ER_CON_COUNT_ERROR | 08004 | Too many connections (max_connections reached). | |
| ER_DBACCESS_DENIED_ERROR | 42000 | User has no privileges on the database. | |
| ER_ACCESS_DENIED_ERROR | 28000 | Access denied - wrong user, host or password. | |
| ER_NO_DB_ERROR | 3D000 | No database selected. | |
| ER_BAD_NULL_ERROR | 23000 | Column cannot be NULL. | |
| ER_BAD_DB_ERROR | 42000 | Unknown database. | |
| ER_TABLE_EXISTS_ERROR | 42S01 | Table already exists. | |
| ER_BAD_TABLE_ERROR | 42S02 | Unknown table (DROP TABLE). | |
| ER_NON_UNIQ_ERROR | 23000 | Column name is ambiguous in a join. | |
| ER_BAD_FIELD_ERROR | 42S22 | Unknown column. | |
| ER_WRONG_FIELD_WITH_GROUP | 42000 | Non-aggregated column not in GROUP BY (ONLY_FULL_GROUP_BY). | |
| ER_DUP_FIELDNAME | 42S21 | Duplicate column name. | |
| ER_DUP_KEYNAME | 42000 | Duplicate index name. | |
| ER_DUP_ENTRY | 23000 | Duplicate entry for a PRIMARY/UNIQUE key. | |
| ER_PARSE_ERROR | 42000 | SQL syntax error. | |
| ER_INVALID_DEFAULT | 42000 | Invalid default value for a column. | |
| ER_TOO_LONG_KEY | 42000 | Index key too long (767 / 3072 bytes). | |
| ER_WRONG_AUTO_KEY | 42000 | AUTO_INCREMENT column must be a key. | |
| ER_CANT_DROP_FIELD_OR_KEY | 42000 | Can't DROP column/index - it does not exist. | |
| ER_UPDATE_TABLE_USED | HY000 | Can't modify a table selected from in a subquery. | |
| ER_RECORD_FILE_FULL | HY000 | The table is full. | |
| ER_TOO_BIG_ROWSIZE | 42000 | Row size too large (65,535 bytes or InnoDB page limit). | |
| ER_HOST_NOT_PRIVILEGED | HY000 | Host is not allowed to connect. | |
| ER_WRONG_VALUE_COUNT_ON_ROW | 21S01 | Column count doesn't match value count. | |
| ER_MIX_OF_GROUP_FUNC_AND_FIELDS | 42000 | Aggregate mixed with plain columns without GROUP BY. | |
| ER_TABLEACCESS_DENIED_ERROR | 42000 | Command denied for table (missing privilege). | |
| ER_NO_SUCH_TABLE | 42S02 | Table doesn't exist. | |
| ER_NET_PACKET_TOO_LARGE | 08S01 | Packet bigger than max_allowed_packet. | |
| ER_BLOB_KEY_WITHOUT_LENGTH | 42000 | TEXT/BLOB indexed without a prefix length. | |
| ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE | HY000 | Safe update mode blocked UPDATE/DELETE without key WHERE. | |
| ER_LOCK_WAIT_TIMEOUT | HY000 | Lock wait timeout exceeded. | |
| ER_LOCK_TABLE_FULL | HY000 | Total number of locks exceeds the lock table size. | |
| ER_LOCK_DEADLOCK | 40001 | Deadlock found; transaction rolled back. | |
| ER_CANNOT_ADD_FOREIGN | HY000 | Cannot add foreign key constraint. | |
| ER_NO_REFERENCED_ROW | 23000 | Child row insert/update fails FK (older form). | |
| ER_ROW_IS_REFERENCED | 23000 | Parent row delete/update fails FK (older form). | |
| ER_SPECIFIC_ACCESS_DENIED_ERROR | 42000 | Needs SUPER / SYSTEM_VARIABLES_ADMIN / other privilege. | |
| ER_MASTER_FATAL_ERROR_READING_BINLOG | HY000 | Replica can't read binlog from source. | |
| ER_WARN_DATA_OUT_OF_RANGE | 22003 | Out of range value for column. | |
| WARN_DATA_TRUNCATED | 01000 | Data truncated for column. | |
| ER_CANT_AGGREGATE_2COLLATIONS | HY000 | Illegal mix of collations. | |
| ER_UNKNOWN_COLLATION | HY000 | Unknown collation (e.g. utf8mb4_0900_ai_ci on old server). | |
| ER_OPTION_PREVENTS_STATEMENT | HY000 | Server option (read_only, secure-file-priv) prevents statement. | |
| ER_TRUNCATED_WRONG_VALUE | 22007 | Incorrect / truncated datetime or number value. | |
| ER_NO_DEFAULT_FOR_FIELD | HY000 | Field doesn't have a default value. | |
| ER_TRUNCATED_WRONG_VALUE_FOR_FIELD | HY000 | Incorrect string/integer value for column (charset or type). | |
| ER_DATA_TOO_LONG | 22001 | Data too long for column. | |
| ER_WRONG_VALUE_FOR_TYPE | HY000 | Incorrect value for function (e.g. STR_TO_DATE). | |
| ER_BINLOG_UNSAFE_ROUTINE | HY000 | Function lacks DETERMINISTIC / NO SQL / READS SQL DATA with binlog on. | |
| ER_BINLOG_CREATE_ROUTINE_NEED_SUPER | HY000 | Creating routines needs SUPER with binlog on. | |
| ER_NO_SUCH_USER | HY000 | DEFINER user of view/routine/trigger doesn't exist. | |
| ER_ROW_IS_REFERENCED_2 | 23000 | Cannot delete/update parent row: FK fails. | |
| ER_NO_REFERENCED_ROW_2 | 23000 | Cannot add/update child row: FK fails. | |
| ER_MAX_PREPARED_STMT_COUNT_REACHED | 42000 | Too many prepared statements (max_prepared_stmt_count). | |
| ER_DATA_OUT_OF_RANGE | 22003 | Numeric value out of range in expression (e.g. UNSIGNED minus). | |
| ER_ACCESS_DENIED_NO_PASSWORD_ERROR | 28000 | Access denied (no password; often auth_socket root). | |
| ER_TRUNCATE_ILLEGAL_FK | 42000 | Cannot TRUNCATE a table referenced by a foreign key. | |
| ER_INDEX_COLUMN_TOO_LONG | HY000 | Index column size too large (767 bytes). | |
| ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION | 25006 | Write attempted inside a READ ONLY transaction. | |
| ER_NOT_VALID_PASSWORD | HY000 | Password does not satisfy the validate_password policy. | |
| ER_MUST_CHANGE_PASSWORD | HY000 | Must reset password with ALTER USER first. | |
| ER_FK_NO_INDEX_PARENT | HY000 | Missing index for FK in the referenced table. | |
| ER_FK_CANNOT_OPEN_PARENT | HY000 | Failed to open the referenced (parent) table. |
Server errors 3000 and above (MySQL 5.7 / 8.0+)
Newer server errors added in MySQL 5.7 and 8.0. MariaDB does not use these numbers - its own newer errors live in the 1900s and 4000s with different meanings.
| Error | Symbol | SQLSTATE | Meaning |
|---|---|---|---|
| ER_QUERY_TIMEOUT | HY000 | max_execution_time exceeded. | |
| ER_INVALID_JSON_TEXT | 22032 | Invalid JSON text for a JSON column. | |
| ER_LOCK_NOWAIT | HY000 | Lock not available and NOWAIT was set. | |
| ER_TABLE_WITHOUT_PK | HY000 | Table without primary key refused (sql_require_primary_key). | |
| ER_FK_INCOMPATIBLE_COLUMNS | HY000 | FK columns are incompatible (type/charset mismatch). | |
| ER_CHECK_CONSTRAINT_VIOLATED | HY000 | CHECK constraint violated. | |
| ER_CLIENT_LOCAL_FILES_DISABLED | 42000 | LOAD DATA LOCAL disabled on client or server. | |
| ER_CLIENT_INTERACTION_TIMEOUT | HY000 | Disconnected by server for inactivity (wait_timeout). |
Client errors 2000–2999 (libmysqlclient / connectors)
Generated by the client library, not the server - usually connection, network or authentication-plugin problems. The mysql client reports them with SQLSTATE HY000.
| Error | Symbol | SQLSTATE | Meaning |
|---|---|---|---|
| CR_CONNECTION_ERROR | HY000 | Can't connect through local socket. | |
| CR_CONN_HOST_ERROR | HY000 | Can't connect to MySQL server on host:port. | |
| CR_UNKNOWN_HOST | HY000 | Unknown MySQL server host (DNS). | |
| CR_SERVER_GONE_ERROR | HY000 | MySQL server has gone away. | |
| CR_SERVER_LOST | HY000 | Lost connection to MySQL server during query. | |
| CR_COMMANDS_OUT_OF_SYNC | HY000 | Commands out of sync. | |
| CR_SSL_CONNECTION_ERROR | HY000 | SSL connection error. | |
| CR_AUTH_PLUGIN_CANNOT_LOAD | HY000 | Authentication plugin cannot be loaded (caching_sha2_password). | |
| CR_AUTH_PLUGIN_ERR | HY000 | Authentication plugin reported error (needs secure connection). |
How to find the MySQL error number
- The mysql client prints it directly:
ERROR 1146 (42S02): Table 'shop.orders' doesn't exist- 1146 is the number, 42S02 the SQLSTATE. - For warnings or a silently failed statement, run
SHOW WARNINGS;orSHOW ERRORS;right after it - the Code column is the error number. - Inside stored procedures,
GET DIAGNOSTICS CONDITION 1 @n = MYSQL_ERRNO, @s = RETURNED_SQLSTATE, @m = MESSAGE_TEXT;exposes the number, SQLSTATE and message in a handler. - From a shell on the server,
perror 1062prints the symbol and message for any number (it also decodes OS / InnoDB errno values such as 150). - In MySQL 8.0+,
SELECT * FROM performance_schema.events_errors_summary_global_by_error WHERE SUM_ERROR_RAISED > 0 ORDER BY SUM_ERROR_RAISED DESC;shows which errors the server has raised and how often. - Drivers:
err.errno(mysql-connector-python, mysql2),e.args[0](PyMySQL),SQLException.getErrorCode()(JDBC),MySQLError.Number(Go),errorInfo[1](PHP PDO).
How to use
- Paste the error number (1064), the whole ERROR line from the mysql client or your logs, a symbol like ER_DUP_ENTRY, or a phrase such as Duplicate entry - or click one of the common codes.
- Read the report: number, symbol, SQLSTATE, the typical message, why it happens and how to fix it with concrete SQL or my.cnf settings. For free text the best match is shown first with up to four alternatives.
- Copy the Handle it in code snippet to catch exactly that error by number in a stored procedure, mysql-connector-python, PyMySQL, JDBC, mysql2, go-sql-driver or PHP PDO.
Frequently asked questions
What is the difference between a MySQL error number, symbol and SQLSTATE?
The error number (errno, e.g. 1062) and its symbol (ER_DUP_ENTRY) identify one specific MySQL error; the symbol is simply the constant name used in the MySQL source and by drivers such as mysql2 (err.code). The SQLSTATE (e.g. 23000) is a five-character code from the SQL standard, and it is much coarser: dozens of MySQL errors share HY000 or 23000. Client-library errors in the 2000-2999 range always report HY000. For reliable error handling, compare the number - getErrorCode() in JDBC, err.errno in Python and Node.js, MySQLError.Number in Go.
Are MariaDB error codes the same as MySQL error codes?
Mostly for the classic ones. MariaDB forked from MySQL 5.5 and kept the 1000-1999 server numbers, so 1045, 1062, 1064, 1146, 1205, 1213, 1451 and 1452 mean the same thing on both. Client errors 2000-2999 come from the client library and also match. They diverge for newer codes: MySQL 5.7/8.0 errors from 3000 upward (such as 3819 check constraint violated or 4031 inactivity disconnect) do not exist in MariaDB, and MariaDB added its own errors in the 1900s and 4000s with different meanings. Check the MariaDB error reference for any code above 1900.
How can I debug a MySQL error against the actual schema faster?
Most errors - 1054 unknown column, 1146 table doesn't exist, 1452 foreign key fails, 1366 incorrect string value - are about the schema, so you need to see the table definition next to the failing statement. Run SHOW CREATE TABLE and SHOW WARNINGS after the statement, or use Chat2DB: download the desktop client at https://chat2db.ai/download or open the web app at https://app.chat2db.ai, connect to MySQL or MariaDB, run the query and let the AI assistant explain the error and propose the corrected SQL with the table structure in view.
