prestodb/presto · error · AccessDeniedException
Cannot add a constraint to table %s%s
Error message
Cannot add a constraint to table %s%s
What it means
denyAddConstraint throws AccessDeniedException when the access control layer denies adding a constraint to the given table. Adding constraints (e.g. primary keys, check constraints) is authorized via checkCanAddConstraint before the connector applies the change.
Source
Thrown at presto-spi/src/main/java/com/facebook/presto/spi/security/AccessDeniedException.java:477
public static void denyDropConstraint(String tableName)
{
denyDropConstraint(tableName, null);
}
public static void denyDropConstraint(String tableName, String extraInfo)
{
throw new AccessDeniedException(format("Cannot drop a constraint from table %s%s", tableName, formatExtraInfo(extraInfo)));
}
public static void denyAddConstraint(String tableName)
{
denyAddConstraint(tableName, null);
}
public static void denyAddConstraint(String tableName, String extraInfo)
{
throw new AccessDeniedException(format("Cannot add a constraint to table %s%s", tableName, formatExtraInfo(extraInfo)));
}
private static Object formatExtraInfo(String extraInfo)
{
if (extraInfo == null || extraInfo.isEmpty()) {
return "";
}
return ": " + extraInfo;
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Grant ADD CONSTRAINT / ALTER privilege to the principal in the access-control policy
- Confirm the DDL targets a table covered by an existing allow rule (wildcards vs explicit names)
- Use a privileged migration account for schema governance changes
- If the connector/catalog does not support the constraint type, use an alternative mechanism instead of forcing policy changes
Example fix
// before
{"catalog": "hive", "group": "data-eng", "privileges": ["SELECT", "INSERT"]}
// after
{"catalog": "hive", "group": "data-eng", "privileges": ["SELECT", "INSERT", "ADD CONSTRAINT"]} Defensive patterns
Strategy: try-catch
Validate before calling
// confirm ADD CONSTRAINT grant before DDL
if (!grants(user, catalog, table).contains("ADD CONSTRAINT")) {
throw new IllegalStateException("ADD CONSTRAINT not granted");
} Type guard
boolean canAddConstraint(String user, String table, Map<String, Set<String>> grants) {
return grants.getOrDefault(user, Set.of()).stream().anyMatch(g -> g.contains("ADD CONSTRAINT"));
} Try / catch
try {
conn.execute("ALTER TABLE t ADD CONSTRAINT pk_t PRIMARY KEY (id)");
} catch (AccessDeniedException e) {
LOG.warn("ADD CONSTRAINT denied: %s", e.getMessage());
throw e;
} Prevention
- Add ADD CONSTRAINT to policy privilege lists for governed DDL users
- Keep table-name rules (wildcards vs explicit) aligned with the DDL targets
- Test constraint DDL against staging policies before rollout
- Review audit logs of denied constraint operations
When it happens
Trigger: A connector calls checkCanAddConstraint; its policy rejects the operation and calls denyAddConstraint(tableName, extraInfo), producing 'Cannot add a constraint to table <table><extraInfo>'.
Common situations: Enforcing data-integrity constraints in governance-heavy environments where DDL is locked down; users with table write but not alter privileges; policies enumerating privileges and missing ADD CONSTRAINT.
Related errors
- Cannot drop a constraint from table %s%s
- Cannot set role %s
- Cannot create branch on table %s%s
- Cannot create tag on table %s%s
- Cannot drop a branch from table %s%s
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/64159b3bc413959c.
Report an issue: GitHub.