prestodb/presto · error · IllegalStateException
Materialized view owner is required when legacy_materialized
Error message
Materialized view owner is required when legacy_materialized_views=false. This indicates a materialized view created before the security mode feature was added. Set session property legacy_materialized_views=true to refresh this view, or drop and recreate the view.
What it means
buildOwnerSession enforces that materialized views created under the newer security model (legacy_materialized_views=false) have an owner recorded. When the owner is absent (view predates the security-mode feature), refresh cannot establish the owner identity, so it fails fast with this IllegalStateException and guidance to use the legacy flag or recreate the view.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/MaterializedViewUtils.java:111
public static final QualifiedName APPROX_DISTINCT = QualifiedName.of("APPROX_DISTINCT");
public static final QualifiedName APPROX_SET = QualifiedName.of("APPROX_SET");
public static final Set<QualifiedName> ASSOCIATIVE_REWRITE_FUNCTIONS = ImmutableSet.of(MIN, MAX, SUM, COUNT);
// TODO: Add count to NonAssociativeFunctionHandler, add more functions
public static final Map<QualifiedName, MaterializedViewUtils.NonAssociativeFunctionHandler> NON_ASSOCIATIVE_REWRITE_FUNCTIONS = ImmutableMap.of(
AVG, new MaterializedViewUtils.AvgRewriteHandler(),
APPROX_DISTINCT, new MaterializedViewUtils.ApproxDistinctRewriteHandler());
public static final Set<QualifiedName> SUPPORTED_FUNCTION_CALLS = Sets.union(ASSOCIATIVE_REWRITE_FUNCTIONS, NON_ASSOCIATIVE_REWRITE_FUNCTIONS.keySet());
private MaterializedViewUtils() {}
public static Session buildOwnerSession(Session session, Optional<String> owner, SessionPropertyManager sessionPropertyManager, String catalog, String schema)
{
// When legacy_materialized_views=false, owner must be present for REFRESH operations
if (!isLegacyMaterializedViews(session) && !owner.isPresent()) {
throw new IllegalStateException(
"Materialized view owner is required when legacy_materialized_views=false. " +
"This indicates a materialized view created before the security mode feature was added. " +
"Set session property legacy_materialized_views=true to refresh this view, or drop and recreate the view.");
}
Identity identity = getOwnerIdentity(owner, session);
Session.SessionBuilder builder = Session.builder(sessionPropertyManager)
.setQueryId(session.getQueryId())
.setTransactionId(session.getTransactionId().orElse(null))
.setIdentity(identity)
.setSource(session.getSource().orElse(null))
.setCatalog(catalog)
.setSchema(schema)
.setTimeZoneKey(session.getTimeZoneKey())
.setLocale(session.getLocale())
.setRemoteUserAddress(session.getRemoteUserAddress().orElse(null))
.setUserAgent(session.getUserAgent().orElse(null))View on GitHub (pinned to 55bb57d202)
Solutions
- Set session property legacy_materialized_views=true for the refresh session of this old view
- Drop and recreate the materialized view so an owner is recorded in its metadata
- Update the view metadata/owner if the deployment provides a migration path
- Audit old views after upgrading and migrate them proactively
Example fix
// before REFRESH MATERIALIZED VIEW catalog.schema.mv; // after SET SESSION catalog.legacy_materialized_views = true; REFRESH MATERIALIZED VIEW catalog.schema.mv;
Defensive patterns
Strategy: validation
Validate before calling
-- check owner before refresh SELECT owner FROM system.metadata.materialized_views WHERE ... ; -- if owner is null, set: SET SESSION <catalog>.legacy_materialized_views = true;
Try / catch
try { refreshMaterializedView(...); } catch (IllegalStateException e) { if (e.getMessage().contains("Materialized view owner is required")) { setSessionLegacyMaterializedViews(true); retry(); } else { throw e; } } Prevention
- After upgrading, audit and recreate legacy materialized views so owners are recorded
- Keep legacy_materialized_views=true only for refresh jobs touching old views
- Document the security-mode migration for MV owners
- Include owner in MV DDL reviews
When it happens
Trigger: Running REFRESH MATERIALIZED VIEW (or equivalent buildOwnerSession path) with legacy_materialized_views=false while the view metadata has Optional.empty() owner, typically a view created before the owner/security feature was introduced.
Common situations: Upgraded clusters: old materialized views lack owners; ops run scheduled refresh jobs against them; users unset legacy_materialized_views cluster-wide but old views remain.
Related errors
- INVALID_TABLE_PROPERTY
- Error setting up SSL:
- Next URI host and port %s are different than current %s
- INVALID_VIEW
- Materialized view already exists
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/b45c49fdac4630d3.
Report an issue: GitHub.