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

  1. List existing roles (e.g. via the catalog's role metadata or SHOW-style tooling) and correct the role name in the REVOKE statement
  2. Create the missing role first if it is genuinely needed
  3. 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

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.