This MySQL error occurs when attempting to use database privileges through a role that hasn't been properly granted to a user. Roles in MySQL provide a way to group privileges and assign them to users collectively. The error typically appears when executing SQL statements that require specific permissions managed through roles.
The ER_ROLE_NOT_GRANTED error (MySQL error code 3530) occurs when a user attempts to exercise privileges through a role that hasn't been granted to them, or when trying to manipulate role assignments without proper authorization. Key aspects of this error: 1. **Role-Based Privilege Management**: MySQL 8.0+ introduced role-based access control (RBAC) where privileges are granted to roles, and roles are then granted to users. This provides more manageable privilege administration. 2. **Role Activation**: Even when a role is granted to a user, it must be "active" for the user to exercise its privileges. Roles can be granted but not automatically active. 3. **Hierarchical Role System**: MySQL supports role hierarchies where roles can be granted to other roles, creating complex privilege inheritance chains. 4. **Session-Specific Role Activation**: Role activation can be session-specific, meaning a user might have different active roles in different connections. This error is common in environments using MySQL's role feature for privilege management, especially during application deployment, user onboarding, or privilege restructuring.
First, verify what roles are granted to the current user and which are active:
-- Check current user
SELECT CURRENT_USER(), USER();
-- List all roles granted to current user
SHOW GRANTS FOR CURRENT_USER();
-- Alternative: query the grants table
SELECT * FROM mysql.role_edges WHERE TO_USER = USER();
-- Check which roles are currently active
SELECT CURRENT_ROLE();
-- List all available roles in the database
SELECT * FROM mysql.roles_mapping;
-- Check role grants with details
SELECT
GRANTEE,
GRANTED_ROLE,
IS_GRANTABLE,
IS_DEFAULT
FROM information_schema.APPLICABLE_ROLES
WHERE GRANTEE = CURRENT_USER();This will show you what roles are granted to the user and whether they're marked as default roles.
If the role isn't granted to the user, grant it with appropriate privileges:
-- Grant role to user (requires appropriate privileges)
GRANT 'app_user_role' TO 'username'@'host';
-- Grant with admin option (allows user to grant to others)
GRANT 'app_user_role' TO 'username'@'host' WITH ADMIN OPTION;
-- Make role default (automatically active on login)
GRANT 'app_user_role' TO 'username'@'host';
SET DEFAULT ROLE 'app_user_role' FOR 'username'@'host';
-- Or set all granted roles as default
SET DEFAULT ROLE ALL FOR 'username'@'host';
-- Verify the grant worked
SHOW GRANTS FOR 'username'@'host';
-- Check from different perspective
SELECT * FROM mysql.role_edges
WHERE FROM_USER = 'username' AND FROM_HOST = 'host';Note: You need appropriate privileges (typically SUPER or GRANT OPTION on the role) to grant roles.
If the role is granted but not active, activate it for the current session:
-- Activate specific role
SET ROLE 'app_user_role';
-- Activate multiple roles
SET ROLE 'role1', 'role2';
-- Activate all granted roles
SET ROLE ALL;
-- Activate all except some roles
SET ROLE ALL EXCEPT 'admin_role';
-- Check current active roles
SELECT CURRENT_ROLE();
-- Verify privileges are now available
SHOW GRANTS FOR CURRENT_USER();
-- Test with a privilege check
SELECT
PRIVILEGE_TYPE,
IS_GRANTABLE
FROM information_schema.USER_PRIVILEGES
WHERE GRANTEE = CURRENT_USER();Role activation is session-specific. Each new connection may need role activation unless default roles are configured.
To avoid manually activating roles in each session, configure default roles:
-- Set specific role as default for user
SET DEFAULT ROLE 'app_user_role' TO 'username'@'host';
-- Set all granted roles as default
SET DEFAULT ROLE ALL TO 'username'@'host';
-- Set no default roles (manual activation required)
SET DEFAULT ROLE NONE TO 'username'@'host';
-- Check current default role configuration
SELECT
DEFAULT_ROLE_USER,
DEFAULT_ROLE_HOST,
DEFAULT_ROLE_ROLE
FROM mysql.default_roles
WHERE DEFAULT_ROLE_USER = 'username' AND DEFAULT_ROLE_HOST = 'host';
-- Alternative: check through performance schema
SELECT * FROM performance_schema.default_roles;
-- Apply changes globally (requires appropriate privileges)
FLUSH PRIVILEGES;Default roles are automatically activated when the user connects, eliminating the need for SET ROLE in each session.
If using role hierarchies, verify the grant chain is complete:
-- Check role-to-role grants
SELECT
FROM_USER AS parent_role,
TO_USER AS child_role
FROM mysql.role_edges
WHERE FROM_USER LIKE '%role%' AND TO_USER LIKE '%role%';
-- Check if role has required parent role grants
WITH RECURSIVE role_tree AS (
SELECT TO_USER AS child_role, FROM_USER AS parent_role
FROM mysql.role_edges
WHERE TO_USER = 'target_role'
UNION ALL
SELECT r.TO_USER, r.FROM_USER
FROM mysql.role_edges r
INNER JOIN role_tree rt ON r.TO_USER = rt.parent_role
)
SELECT * FROM role_tree;
-- Grant role to another role (creating hierarchy)
GRANT 'parent_role' TO 'child_role';
-- Check effective privileges through role hierarchy
SHOW GRANTS FOR 'username'@'host' USING 'app_user_role';
-- Revoke and regrant if hierarchy is broken
REVOKE 'app_user_role' FROM 'username'@'host';
GRANT 'app_user_role' TO 'username'@'host';
SET DEFAULT ROLE 'app_user_role' FOR 'username'@'host';Role hierarchies can be complex. Ensure all necessary parent roles are granted and active.
For applications with connection pooling, ensure roles are handled correctly:
-- Check connection attributes (for debugging)
SELECT * FROM performance_schema.session_connect_attrs
WHERE PROCESSLIST_ID = CONNECTION_ID();
-- Check current session role state
SELECT
CURRENT_USER(),
CURRENT_ROLE(),
@@activate_all_roles_on_login
FROM DUAL;
-- MySQL configuration for automatic role activation
SET GLOBAL activate_all_roles_on_login = ON;
-- Or in my.cnf:
[mysqld]
activate_all_roles_on_login = ONApplication code examples:
# Python - Ensure role activation on connection
import mysql.connector
config = {
'user': 'username',
'password': 'password',
'database': 'mydb',
'host': 'localhost',
'port': 3306,
'autocommit': True,
'connection_timeout': 10
}
connection = mysql.connector.connect(**config)
cursor = connection.cursor()
# Activate role after connection
cursor.execute("SET ROLE 'app_user_role'")
connection.commit()// PHP - Role activation
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'username', 'password');
$pdo->exec("SET ROLE 'app_user_role'");Configure connection pools to execute SET ROLE after establishing connections.
The ER_ROLE_NOT_GRANTED error involves several advanced MySQL role management concepts:
1. Role Activation Modes: MySQL supports different role activation modes:
- SET ROLE: Manual activation per session
- SET DEFAULT ROLE: Automatic activation on login
- activate_all_roles_on_login: Global setting for automatic activation
2. Role Hierarchies and Inheritance: Roles can be granted to other roles, creating privilege inheritance chains. When a role is activated, all privileges from parent roles become available.
3. Mandatory Roles: MySQL 8.0.19+ supports mandatory roles that are always active for all users, useful for baseline security policies.
4. Role Privilege Updates: When privileges are added to a role, all users with that role (active or default) immediately gain the new privileges.
5. Performance Schema Monitoring: Use Performance Schema tables (performance_schema.active_roles, performance_schema.role_edges) to monitor role usage and grants.
6. Security Considerations:
- Role grants are stored in mysql.role_edges
- Default roles in mysql.default_roles
- Mandatory roles in mysql.mandatory_roles (global variable)
- Regular privilege audits should include role assignments
7. Migration from Legacy Systems: When migrating from MySQL 5.7 or earlier without role support, plan role design carefully to match existing user/privilege structures.
8. Cloud Database Considerations: Managed MySQL services (AWS RDS, Google Cloud SQL, Azure Database for MySQL) fully support roles but may have specific limitations or best practices.
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