prestodb/presto · error · PinotException
PINOT_DATA_FETCH_EXCEPTION_OR_PINOT_EXCEPTION
PINOT_DATA_FETCH_EXCEPTION_OR_PINOT_EXCEPTION
Error message
Encountered %d pinot exceptions for split %s: %s
What it means
After receiving a DataTable from a Pinot server, the connector checks the table's exception map. If Pinot reported any server-side exceptions while executing the segment query, the connector wraps them into a single PinotException — retriable PINOT_DATA_FETCH_EXCEPTION when markDataFetchExceptionsAsRetriable is on, otherwise PINOT_EXCEPTION — including the count, split, and exception list.
Source
Thrown at presto-pinot-toolkit/src/main/java/com/facebook/presto/pinot/PinotSegmentPageSource.java:104
PinotStreamingQueryClient pinotStreamingQueryClient,
PinotSplit split,
List<PinotColumnHandle> columnHandles)
{
this.pinotConfig = requireNonNull(pinotConfig, "pinotConfig is null");
this.split = requireNonNull(split, "split is null");
this.columnHandles = requireNonNull(columnHandles, "columnHandles is null");
this.session = requireNonNull(session, "session is null");
this.columnTypes = columnHandles.stream()
.map(PinotSegmentPageSource::getTypeForBlock)
.collect(Collectors.toList());
this.pinotStreamingQueryClient = requireNonNull(pinotStreamingQueryClient, "pinotStreamingQueryClient is null");
}
public static void checkExceptions(DataTable dataTable, PinotSplit split, boolean markDataFetchExceptionsAsRetriable)
{
List<String> exceptions = dataTable.getExceptions().values().stream().toList();
if (!exceptions.isEmpty()) {
throw new PinotException(
markDataFetchExceptionsAsRetriable ? PINOT_DATA_FETCH_EXCEPTION : PINOT_EXCEPTION,
split.getSegmentPinotQuery(),
String.format("Encountered %d pinot exceptions for split %s: %s", exceptions.size(), split, exceptions));
}
int numColumnsExpected = split.getExpectedColumnHandles().size();
int numColumnsActual = dataTable.getDataSchema().size();
if (numColumnsActual != numColumnsExpected) {
throw new PinotException(
PINOT_EXCEPTION,
split.getSegmentPinotQuery(),
String.format("Expected pinot to contain %d columns but got %d: %s", numColumnsExpected, numColumnsActual, dataTable.getDataSchema()));
}
}
@Override
public long getCompletedBytes()
{
return completedBytes;View on GitHub (pinned to 55bb57d202)
Solutions
- Read the embedded exception list in the message to see the actual Pinot server error and address that root cause
- If transient, retry the query; consider setting pinot.mark-data-fetch-exceptions-as-retriable=true (session property) so fetch exceptions are retried
- Check Pinot server/broker logs and segment health; reload or repair failing segments
- Reduce query resource usage (limits, timeouts, column count) if Pinot is rejecting the query on quotas
Example fix
// before SELECT * FROM huge_table -- server times out per segment // after SELECT needed_cols FROM huge_table WHERE time_col > ... LIMIT 100000
Defensive patterns
Strategy: retry
Try / catch
catch (PinotException e) {
if (e.getErrorCode() == PINOT_DATA_FETCH_EXCEPTION.toErrorCode().getCode()
|| e.getErrorCode() == PINOT_EXCEPTION.toErrorCode().getCode()) {
// inspect message for embedded Pinot exceptions; retry with backoff if transient
}
} Prevention
- Enable pinot.mark-data-fetch-exceptions-as-retriable session property for transient-tolerant workloads
- Monitor Pinot server health and segment status
- Keep queries within Pinot timeouts/limits to avoid server-side rejections
When it happens
Trigger: getNextPage receives a server response whose DataTable has non-empty getExceptions(); checkExceptions then throws before returning any page.
Common situations: Pinot server-side query failures: timeouts, segment load errors, broker/server resource limits, query limits exceeded, or corrupted segments on the server.
Related errors
- PINOT_DATA_FETCH_EXCEPTION
- PINOT_EXCEPTION
- PINOT_UNSUPPORTED_COLUMN_TYPE
- PINOT_UNEXPECTED_RESPONSE
- PINOT_INSUFFICIENT_SERVER_RESPONSE
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/8bc1b767f13a637b.
Report an issue: GitHub.