prestodb/presto · error · SemanticException

INVALID_PRIVILEGE

INVALID_PRIVILEGE

Error message

Unknown privilege: '%s'

What it means

parsePrivilege matches the privilege keyword in a GRANT/REVOKE statement case-insensitively against the Privilege enum values. If no enum matches, the statement is rejected with INVALID_PRIVILEGE before any permission change. Only privileges defined in the Presto Privilege enum are accepted.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/RevokeTask.java:87

        // verify current identity has permissions to revoke permissions
        for (Privilege privilege : privileges) {
            accessControl.checkCanRevokeTablePrivilege(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), privilege, tableName, createPrincipal(statement.getGrantee()), statement.isGrantOptionFor());
        }

        metadata.revokeTablePrivileges(session, tableName, privileges, createPrincipal(statement.getGrantee()), statement.isGrantOptionFor());
        return immediateFuture(null);
    }

    private static Privilege parsePrivilege(Revoke statement, String privilegeString)
    {
        for (Privilege privilege : Privilege.values()) {
            if (privilege.name().equalsIgnoreCase(privilegeString)) {
                return privilege;
            }
        }

        throw new SemanticException(INVALID_PRIVILEGE, statement, "Unknown privilege: '%s'", privilegeString);
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Use one of the supported privilege names (e.g. SELECT, INSERT, UPDATE, DELETE — exactly the Privilege enum values)
  2. Omit the privilege to apply all privileges in the statement
  3. Check the Presto version's Privilege enum for the exact supported set

Example fix

// before
REVOKE TRUNCATE ON hive.default.orders FROM USER alice;
// after
REVOKE DELETE ON hive.default.orders FROM USER alice;
Defensive patterns

Strategy: validation

Validate before calling

Set<String> valid = Arrays.stream(Privilege.values())
        .map(p -> p.name().toUpperCase())
        .collect(Collectors.toSet());
if (!valid.contains(privilegeString.toUpperCase())) {
    throw new IllegalArgumentException("Unknown privilege: " + privilegeString);
}

Try / catch

try {
    return revokeTask.execute(statement, ...);
} catch (SemanticException e) {
    if (e.getCode() == SemanticErrorCode.INVALID_PRIVILEGE) {
        // map or reject the privilege keyword before retry
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: REVOKE <word> ... ON <table> where <word> does not equal (ignoring case) any Privilege enum name, e.g. 'WRITE', 'DROP', 'ALL PRIVILEGES'.

Common situations: Using privileges from other SQL dialects (INSERT/UPDATE/DELETE depend on dialect); guessing privilege names; copy-pasting GRANT syntax from another database.

Related errors


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