prestodb/presto · error · PrestoException

GENERIC_INTERNAL_ERROR

GENERIC_INTERNAL_ERROR

Error message

TaskResultFetcher is closed with %s pages left in the buffer

What it means

HttpNativeExecutionTaskResultFetcher buffers serialized pages fetched from native workers. On stop(), if all fetches succeeded (success == true) but the pageBuffer still contains un-consumed pages, Presto throws GENERIC_INTERNAL_ERROR because silently discarding successfully fetched result pages would lose query output data.

Source

Thrown at presto-spark-base/src/main/java/com/facebook/presto/spark/execution/nativeprocess/HttpNativeExecutionTaskResultFetcher.java:104

        this.taskHasResult = requireNonNull(taskHasResult, "taskHasResult is null");
    }

    public void start()
    {
        scheduledFuture = scheduler.scheduleAtFixedRate(this::doGetResults,
                0,
                (long) FETCH_INTERVAL.getValue(),
                FETCH_INTERVAL.getUnit());
    }

    public void stop(boolean success)
    {
        if (scheduledFuture != null) {
            scheduledFuture.cancel(false);
        }

        if (success && !pageBuffer.isEmpty()) {
            throw new PrestoException(GENERIC_INTERNAL_ERROR, format("TaskResultFetcher is closed with %s pages left in the buffer", pageBuffer.size()));
        }
    }

    /**
     * Blocking call to poll from result buffer. Blocks until content becomes
     * available in the buffer, or until timeout is hit.
     *
     * @return the first {@link SerializedPage} result buffer contains.
     */
    public Optional<SerializedPage> pollPage()
            throws InterruptedException
    {
        throwIfFailed();
        SerializedPage page = pageBuffer.poll((long) POLL_TIMEOUT.getValue(), POLL_TIMEOUT.getUnit());
        if (page != null) {
            bufferMemoryBytes.addAndGet(-page.getSizeInBytes());
            return Optional.of(page);
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Consume all pages via getNextPage/poll until the buffer is empty before calling stop()
  2. If intentionally abandoning results, use the failure/cancel path (success=false) rather than a successful stop with data remaining
  3. Check for early-exit logic (limit/partial consumption) that skips buffered pages and drain the fetcher explicitly

Example fix

// before
resultFetcher.stop(); // throws if pages remain
// after
while (!resultFetcher.isBufferEmpty()) {
    resultFetcher.getNextPage(NEXT_PAGE_TOKEN, Duration.ofSeconds(30));
}
resultFetcher.stop();
Defensive patterns

Strategy: validation

Validate before calling

// before stop()
if (resultFetcher.hasBufferedPages()) {
    // drain or explicitly acknowledge discarding results
}

Try / catch

try {
    resultFetcher.stop();
} catch (PrestoException e) {
    // pages were fetched but never consumed; log lost-output diagnostics
}

Prevention

When it happens

Trigger: stop() is called while pageBuffer is non-empty and success is true — i.e., the caller finished/cancelled polling (e.g., abandoned getNextPage polling after task completion) without draining all buffered pages from the native worker.

Common situations: Query cancellation or early termination of result consumption after the native task already wrote all pages; upstream logic that stops polling once a limit is reached without draining the buffer; a bug causing getNextPage to not be called for all buffered output.

Related errors


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