prestodb/presto · error · PrestoException

QUERY_PLANNING_TIMEOUT

QUERY_PLANNING_TIMEOUT

Error message

The query planner exceeded the timeout of %s.

What it means

During relational planning, RelationPlanner.checkInterruption polls the current thread's interrupt flag; if it is set, planning is assumed to have exceeded the analyzer timeout (query.analyzer-timeout / query planner timeout) and QUERY_PLANNING_TIMEOUT is thrown. The engine interrupts planning threads once the configured timeout elapses.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/planner/RelationPlanner.java:1377

                    outputs.size());

            int fieldId = 0;
            for (Field field : descriptor.getVisibleFields()) {
                int fieldIndex = descriptor.indexOf(field);
                variableMapping.put(outputs.get(fieldId), childOutputVariables.get(fieldIndex));
                fieldId++;
            }

            sources.add(relationPlan.getRoot());
        }

        return new SetOperationPlan(sources.build(), variableMapping.build());
    }

    private void checkInterruption()
    {
        if (Thread.currentThread().isInterrupted()) {
            throw new PrestoException(QUERY_PLANNING_TIMEOUT, String.format("The query planner exceeded the timeout of %s.", getQueryAnalyzerTimeout(session).toString()));
        }
    }

    private PlanBuilder initializePlanBuilder(RelationPlan relationPlan)
    {
        TranslationMap translations = new TranslationMap(relationPlan, analysis, lambdaDeclarationToVariableMap);

        // Make field->variable mapping from underlying relation plan available for translations
        // This makes it possible to rewrite FieldOrExpressions that reference fields from the underlying tuple directly
        translations.setFieldMappings(relationPlan.getFieldMappings());

        return new PlanBuilder(translations, relationPlan.getRoot());
    }

    private PlanNode distinct(PlanNode node)
    {
        return new AggregationNode(
                node.getSourceLocation(),

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Increase query.analyzer-timeout (config property or session property) to give planning more time
  2. Simplify the query: reduce set-operation depth, break into staged queries/materialized steps
  3. Retry the query during lower cluster load if planning was merely slow, not intrinsically too complex
  4. Profile the plan complexity; very large generated SQL may indicate a client-side generation bug

Example fix

// before
query.analyzer-timeout=1m
// after
query.analyzer-timeout=10m
Defensive patterns

Strategy: retry

Try / catch

try {
    result = execute(sql);
} catch (PrestoException e) {
    if (e.getErrorCode().getName().equals("QUERY_PLANNING_TIMEOUT")) {
        // one retry, optionally with a raised analyzer timeout
        session.setProperty("query_analyzer_timeout", "20m");
        result = execute(sql);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Planning a very complex relation (huge set operations, deep expression trees) that takes longer than the configured planner/analyzer timeout, causing the worker thread to be interrupted and the next checkInterruption() call to throw.

Common situations: Queries with enormous UNION/INTERSECT trees or thousands of joins; clusters with a low query.analyzer-timeout setting; shared fleet overload slowing planning past the deadline.

Understand the failure class

Related errors


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