MySQL Error 1144 occurs when a GRANT or REVOKE statement uses privileges that cannot be applied to the specified object. The error typically arises from privilege scope mismatches, missing PROCEDURE/FUNCTION keywords, or attempting to grant global-only privileges at table level. Fixing it requires matching privilege scope to the target object type.
MySQL Error 1144 (ER_ILLEGAL_GRANT_FOR_TABLE) indicates that your GRANT or REVOKE command violates MySQL permission syntax rules. MySQL has strict rules about which privileges can be granted on which object types. Different privileges have different applicable scopes: some are global-only (like PROCESS or SUPER), some apply to databases, some to tables, and some specifically to stored routines. When you try to use a privilege in an invalid scope or forget required keywords like PROCEDURE or FUNCTION, MySQL rejects the command with this error. The error code 42000 (SQLSTATE) represents a syntax error or access violation in the privilege granting system.
Copy your failing GRANT or REVOKE command and examine it carefully. Check the MySQL manual for the correct syntax of the privilege level you need.
Common mistake:
GRANT LOCK TABLES ON database.table TO user@localhost; -- ERROR 1144Correct syntax:
GRANT LOCK TABLES ON database.* TO user@localhost; -- Database level, not tableIf your command includes EXECUTE privilege, ensure you specify the PROCEDURE or FUNCTION keyword to indicate the object type.
Mistake:
GRANT EXECUTE ON mydb.stored_proc TO user@localhost; -- ERROR 1144Correct:
GRANT EXECUTE ON PROCEDURE mydb.stored_proc TO user@localhost;
GRANT EXECUTE ON FUNCTION mydb.my_function TO user@localhost;Some MySQL privileges can only be granted at the global level. Move these from database/table scope to global scope.
Global-only privileges requiring *.*:
- PROCESS
- SUPER
- RELOAD
- SHOW DATABASES
- SHUTDOWN
- FILE
- REPLICATION MASTER ADMIN
- ROLE_ADMIN (MySQL 8.0+)
Example fix:
-- Wrong: Database level
GRANT PROCESS ON mydb.* TO user@localhost; -- ERROR 1144
-- Correct: Global level
GRANT PROCESS ON *.* TO user@localhost;If you need to grant mixed privilege types, break them into separate statements with appropriate scopes.
Instead of:
GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES ON mydb.users TO user@localhost; -- ERROR 1144Use:
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.users TO user@localhost;
GRANT LOCK TABLES ON mydb.* TO user@localhost;Some privileges only exist in specific MySQL versions. If using a privilege not supported in your version, remove it or upgrade MySQL.
Run this to check your version:
SELECT VERSION();Version-specific examples:
- ROLE_ADMIN (MySQL 8.0+)
- SYSTEM_VARIABLES_ADMIN (MySQL 8.0.14+)
- BACKUP_ADMIN (MySQL 8.0.3+)
If the privilege doesn't exist in your version, either upgrade or remove it from the GRANT statement.
Once you've fixed the syntax, execute the corrected command.
Example complete command with correct syntax:
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.users TO 'appuser'@'localhost';
GRANT CREATE ON mydb.* TO 'appuser'@'localhost';
GRANT EXECUTE ON PROCEDURE mydb.generate_report TO 'appuser'@'localhost';
GRANT LOCK TABLES ON mydb.* TO 'appuser'@'localhost';Verify success with:
SHOW GRANTS FOR 'appuser'@'localhost';For automation and infrastructure-as-code tools (Terraform, Ansible, Salt Stack): These tools often construct GRANT statements programmatically and may not account for privilege scope restrictions. Always test your generated GRANT statements manually before automation deployment. When using Ansible mysql_user module or similar, ensure your templates include the object_type parameter (PROCEDURE, FUNCTION, TABLE) where applicable. For MySQL 8.0+ with role-based access control, remember that you can also grant roles to users instead of raw privileges, which can simplify permission management. Column-level privileges (e.g., SELECT(column_name)) have even stricter scope limitations and cannot be mixed with routine privileges in the same statement.
ERROR 1064: You have an error in your SQL syntax
How to fix "ERROR 1064: You have an error in your SQL syntax" in MySQL
ERROR 1054: Unknown column in field list
Unknown column in field list
ER_WINDOW_RANGE_FRAME_NUMERIC_TYPE (3589): RANGE frame requires numeric ORDER BY expression
RANGE frame requires numeric ORDER BY expression in MySQL window functions
CR_ALREADY_CONNECTED (2058): Handle already connected
How to fix "CR_ALREADY_CONNECTED (2058): Handle already connected" in MySQL
ER_WINDOW_DUPLICATE_NAME (3591): Duplicate window name
How to fix ER_WINDOW_DUPLICATE_NAME (3591) in MySQL window functions