prestodb/presto · error · SemanticException

MISSING_ROLE

MISSING_ROLE

Error message

Role '%s' does not exist

What it means

CreateRoleTask.execute throws SemanticException(MISSING_ROLE) when the CREATE ROLE statement specifies a GRANTOR that is a ROLE type but that grantor role does not exist in the catalog's role set. The grantor must be an existing principal for authorization to be meaningful, so Presto rejects the statement before creating the new role.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/CreateRoleTask.java:59

    @Override
    public String getName()
    {
        return "CREATE ROLE";
    }

    @Override
    public ListenableFuture<?> execute(CreateRole statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector, String query)
    {
        String catalog = createCatalogName(session, statement);
        String role = statement.getName().getValueLowerCase();
        Optional<PrestoPrincipal> grantor = statement.getGrantor().map(specification -> createPrincipal(session, specification));
        accessControl.checkCanCreateRole(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), role, grantor, catalog);
        Set<String> existingRoles = metadata.listRoles(session, catalog);
        if (existingRoles.contains(role)) {
            throw new SemanticException(ROLE_ALREADY_EXIST, statement, "Role '%s' already exists", role);
        }
        if (grantor.isPresent() && grantor.get().getType() == ROLE && !existingRoles.contains(grantor.get().getName())) {
            throw new SemanticException(MISSING_ROLE, statement, "Role '%s' does not exist", grantor.get().getName());
        }
        metadata.createRole(session, role, grantor, catalog);
        return immediateFuture(null);
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Create the grantor role first (CREATE ROLE grantor_role) before referencing it as GRANTOR.
  2. Correct the grantor role name (check spelling and that it exists via SHOW ROLES / listRoles).
  3. Omit the GRANTOR clause so the current user becomes the grantor.
  4. Ensure the grantor role exists in the same catalog the new role is being created in.

Example fix

-- before
CREATE ROLE data_scientist GRANTOR ROLE data_eng; -- data_eng missing

-- after
CREATE ROLE data_eng;
CREATE ROLE data_scientist GRANTOR ROLE data_eng;
Defensive patterns

Strategy: validation

Validate before calling

Optional<PrestoPrincipal> grantor = statement.getGrantor().map(spec -> createPrincipal(session, spec));
if (grantor.isPresent() && grantor.get().getType() == ROLE
        && !metadata.listRoles(session, catalog).contains(grantor.get().getName())) {
    throw new IllegalStateException("Grantor role " + grantor.get().getName() + " must be created first");
}

Type guard

boolean grantorRoleMissing(Session session, String catalog, Metadata metadata, PrestoPrincipal grantor) {
    return grantor.getType() == ROLE && !metadata.listRoles(session, catalog).contains(grantor.getName());
}

Try / catch

try {
    createRole(session, statement);
} catch (SemanticException e) {
    if (e.getCode() == MISSING_ROLE) {
        // create the referenced grantor role, then retry
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: CREATE ROLE new_role GRANTOR ROLE some_role where some_role is not in metadata.listRoles for the target catalog (grantor type == ROLE and name not in existingRoles).

Common situations: Typo in the grantor role name; grantor role defined in a different catalog; provisioning scripts that reference roles not yet created; case sensitivity mistakes (names are lowercased).

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/576d49bdc0c3adeb. Report an issue: GitHub.