prestodb/presto · error · SemanticException
MISSING_ROLE
MISSING_ROLE
Error message
Role '%s' does not exist
What it means
Thrown by REVOKE ROLE statements when a role named in the statement (or used as grantor) is not defined in the catalog. Presto validates all referenced roles against the available roles from the metadata/access-control layer before performing any revocation, so nothing is modified when this fires. It is a semantic SQL error, not a runtime failure.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/RevokeRolesTask.java:74
.collect(toImmutableSet());
boolean adminOptionFor = statement.isAdminOptionFor();
Optional<PrestoPrincipal> grantor = statement.getGrantor().map(specification -> createPrincipal(session, specification));
String catalog = createCatalogName(session, statement);
Set<String> availableRoles = metadata.listRoles(session, catalog);
Set<String> specifiedRoles = new LinkedHashSet<>();
specifiedRoles.addAll(roles);
grantees.stream()
.filter(principal -> principal.getType() == ROLE)
.map(PrestoPrincipal::getName)
.forEach(specifiedRoles::add);
if (grantor.isPresent() && grantor.get().getType() == ROLE) {
specifiedRoles.add(grantor.get().getName());
}
for (String role : specifiedRoles) {
if (!availableRoles.contains(role)) {
throw new SemanticException(MISSING_ROLE, statement, "Role '%s' does not exist", role);
}
}
accessControl.checkCanRevokeRoles(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), roles, grantees, adminOptionFor, grantor, catalog);
metadata.revokeRoles(session, roles, grantees, adminOptionFor, grantor, catalog);
return immediateFuture(null);
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- List existing roles (e.g. via the catalog's role metadata or SHOW-style tooling) and correct the role name in the REVOKE statement
- Create the missing role first if it is genuinely needed
- Verify you connected to the catalog where the role exists (roles are catalog-scoped)
Example fix
// before REVOKE role adming FROM USER bob; // after REVOKE role admin FROM USER bob;
Defensive patterns
Strategy: validation
Validate before calling
// Before running REVOKE, confirm each role exists
Set<String> available = metadata.listRoles(session, catalog); // or your connector's role listing
for (String role : roles) {
if (!available.contains(role)) {
throw new IllegalArgumentException("Role not found in " + catalog + ": " + role);
}
} Try / catch
try {
metadata.revokeRoles(session, roles, grantees, adminOptionFor, grantor, catalog);
} catch (SemanticException e) {
if (e.getCode() == SemanticErrorCode.MISSING_ROLE) {
// log and skip unknown role
} else {
throw e;
}
} Prevention
- Keep role definitions in version-controlled provisioning scripts
- Validate role names against listRoles before any GRANT/REVOKE
- Remember roles are catalog-scoped; verify the session catalog
When it happens
Trigger: Executing REVOKE roles FROM grantees (or ADMIN OPTION FOR / grantor of type ROLE) where a role name in the statement is not in the catalog's availableRoles set for the given catalog.
Common situations: Typo in the role name; role was dropped or never created; statement run against the wrong catalog where the role does not exist; case-sensitivity assumptions about role names.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/4e4ffe06c0fbe283.
Report an issue: GitHub.