prestodb/presto · error · AccessDeniedException

View owner '%s' cannot create view that selects from %s%s

Error message

View owner '%s' cannot create view that selects from %s%s

What it means

Thrown when the owner of a view being created does not have permission to SELECT from the source table it references. Presto checks that the view's designated owner can read every source; denyCreateViewWithSelect fires during checkCanCreateViewWithSelect. This prevents users from creating views over data they themselves cannot read (privilege escalation).

Source

Thrown at presto-spi/src/main/java/com/facebook/presto/spi/security/AccessDeniedException.java:282

    public static void denyCreateView(String viewName, String extraInfo)
    {
        throw new AccessDeniedException(format("Cannot create view %s%s", viewName, formatExtraInfo(extraInfo)));
    }

    public static void denyCreateViewWithSelect(String sourceName, Identity identity)
    {
        denyCreateViewWithSelect(sourceName, identity.toConnectorIdentity());
    }

    public static void denyCreateViewWithSelect(String sourceName, ConnectorIdentity identity)
    {
        denyCreateViewWithSelect(sourceName, identity, null);
    }

    public static void denyCreateViewWithSelect(String sourceName, ConnectorIdentity identity, String extraInfo)
    {
        throw new AccessDeniedException(format("View owner '%s' cannot create view that selects from %s%s", identity.getUser(), sourceName, formatExtraInfo(extraInfo)));
    }

    public static void denyRenameView(String viewName, String newViewName)
    {
        denyRenameView(viewName, newViewName, null);
    }

    public static void denyRenameView(String viewName, String newViewName, String extraInfo)
    {
        throw new AccessDeniedException(format("Cannot rename view from %s to %s%s", viewName, newViewName, formatExtraInfo(extraInfo)));
    }

    public static void denyDropView(String viewName)
    {
        denyDropView(viewName, null);
    }

    public static void denyDropView(String viewName, String extraInfo)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Grant the view owner SELECT on the source table, then re-run CREATE VIEW
  2. Change the view owner to a principal that already has SELECT on the source
  3. Rewrite the view to reference only tables the owner can read

Example fix

// before
CREATE VIEW v AS SELECT * FROM secure.t; -- owner lacks SELECT on secure.t
// after (as admin)
GRANT SELECT ON secure.t TO USER viewowner;
CREATE VIEW v AS SELECT * FROM secure.t;
Defensive patterns

Strategy: validation

Validate before calling

// before CREATE VIEW, verify the designated owner can SELECT each source table
for (String source : extractTableNames(query)) {
    if (!catalogAdmin.userHasPrivilege(viewOwner, source, "SELECT")) {
        throw new IllegalStateException("View owner " + viewOwner + " lacks SELECT on " + source);
    }
}

Try / catch

try {
    execute(createViewSql);
} catch (AccessDeniedException e) {
    if (e.getMessage().contains("View owner")) {
        log.error("Grant SELECT on all source tables to the view owner: {}", e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: CREATE VIEW by a user whose owner identity cannot SELECT from the referenced source table; AccessControlManager.checkCanCreateViewWithSelect checks each source against identity.getUser().

Common situations: Run-as semantics: definer-based views where the owner lost SELECT on the base table; migrating views between catalogs; role-based security where the creator has SELECT via their session role but the owner identity does not.

Related errors


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