prestodb/presto · error · PrestoException
INDEX_LOADER_TIMEOUT
INDEX_LOADER_TIMEOUT
Error message
Exceeded the time limit of %s loading indexes for index join
What it means
IndexLoader.load builds the index snapshot for an index join by driving a Driver and awaiting each process() future with a timeout. If the index build does not finish within the configured limit, the library throws INDEX_LOADER_TIMEOUT so the query fails fast instead of hanging.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/operator/index/IndexLoader.java:355
}
public boolean load(List<UpdateRequest> requests)
{
// Generate a RecordSet that only presents index keys that have not been cached and are deduped based on lookupSourceInputChannels
UnloadedIndexKeyRecordSet recordSetForLookupSource = new UnloadedIndexKeyRecordSet(pipelineContext.getSession(), indexSnapshotReference.get(), lookupSourceInputChannels, indexTypes, requests, joinCompiler);
// Drive index lookup to produce the output (landing in indexSnapshotBuilder)
try (Driver driver = driverFactory.createDriver(pipelineContext.addDriverContext())) {
PlanNodeId sourcePlanNodeId = driverFactory.getSourceId().get();
ScheduledSplit split = new ScheduledSplit(0, sourcePlanNodeId, new Split(INDEX_CONNECTOR_ID, new ConnectorTransactionHandle() {}, new IndexSplit(recordSetForLookupSource)));
driver.updateSource(new TaskSource(sourcePlanNodeId, ImmutableSet.of(split), true));
while (!driver.isFinished()) {
ListenableFuture<?> process = driver.process();
try {
process.get(timeout.toMillis(), MILLISECONDS);
}
catch (TimeoutException e) {
throw new PrestoException(INDEX_LOADER_TIMEOUT, format("Exceeded the time limit of %s loading indexes for index join", timeout));
}
catch (ExecutionException e) {
throw new PrestoException(GENERIC_INTERNAL_ERROR, "Error loading index for join", e);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new PrestoException(GENERIC_INTERNAL_ERROR, "Error loading index for join", e);
}
}
}
if (indexSnapshotBuilder.isMemoryExceeded()) {
clearCachedData();
return false;
}
// Generate a RecordSet that presents unique index keys that have not been cached
UnloadedIndexKeyRecordSet indexKeysRecordSet = (lookupSourceInputChannels.equals(allInputChannels))View on GitHub (pinned to 55bb57d202)
Solutions
- Increase the index-loader timeout in the coordinator config (index-loader-timeout)
- Rewrite the join as a regular hash join (disable index join) so a full build is used
- Reduce the amount of data going through the index join with better filtering
- Increase worker resources / parallelism to speed index building
Example fix
// before query-properties: index-loader-timeout=30s // after query-properties: index-loader-timeout=5m (or disable index join for this query)
Defensive patterns
Strategy: retry
Try / catch
try { runIndexJoinQuery(sql); } catch (PrestoException e) { if (e.getErrorCode().getName().equals("INDEX_LOADER_TIMEOUT")) { // increase timeout or fall back to hash join
retryWithHashJoin(sql); } else throw e; } Prevention
- Size the index-loader timeout to your largest index joins
- Filter build-side data so index builds stay small
- Monitor index build durations and alert on timeouts
- Consider join_distribution_type=PARTITIONED to avoid index joins when not needed
When it happens
Trigger: Index join where building/loading the lookup index from the probe-side source takes longer than the index-loader timeout (process.get(timeout) raises TimeoutException).
Common situations: Very large build side for the index join; slow underlying connector for index lookups; too-low 'index-loader-timeout' config for the workload.
Related errors
- GENERIC_INTERNAL_ERROR
- QUERY_PLANNING_TIMEOUT
- QUERY_PLANNING_TIMEOUT
- OPTIMIZER_TIMEOUT
- INVALID_TABLE_PROPERTY
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/b3c435f48a173128.
Report an issue: GitHub.