prestodb/presto · error · PrestoException
DRUID_BROKER_RESULT_ERROR
DRUID_BROKER_RESULT_ERROR
Error message
${rootNode.findValue("errorMessage").asText()} What it means
This PrestoException (DRUID_BROKER_RESULT_ERROR) is thrown by DruidBrokerPageSource.getNextPage when a line of the Druid broker's newline-delimited JSON response contains an "errorMessage" field. Druid's /druid/v2/sql endpoint returns per-row error objects (e.g. {"queryNumber":..., "errorMessage":"..."}) when the SQL query fails server-side, and the connector surfaces that message directly to the user instead of returning bad data. The check is skipped if the query itself selected a column literally named "errorMessage".
Source
Thrown at presto-druid/src/main/java/com/facebook/presto/druid/DruidBrokerPageSource.java:127
if (finished) {
return null;
}
long start = System.nanoTime();
boolean columnHandlesHasErrorMessageField = columnHandles.stream().anyMatch(
handle -> ((DruidColumnHandle) handle).getColumnName().equals("errorMessage"));
try {
String readLine;
while ((readLine = responseStream.readLine()) != null) {
// if read a blank line,it means read finish
if (readLine.isEmpty()) {
finished = true;
break;
}
else {
JsonNode rootNode = OBJECT_MAPPER.readTree(readLine);
if (rootNode.has("errorMessage") && !columnHandlesHasErrorMessageField) {
throw new PrestoException(DRUID_BROKER_RESULT_ERROR, rootNode.findValue("errorMessage").asText());
}
for (int i = 0; i < columnHandles.size(); i++) {
Type type = columnTypes.get(i);
BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(i);
JsonNode value = rootNode.get(((DruidColumnHandle) columnHandles.get(i)).getColumnName());
if (value == null || value.isNull()) {
blockBuilder.appendNull();
continue;
}
if (type instanceof BigintType) {
type.writeLong(blockBuilder, value.longValue());
}
else if (type instanceof DoubleType) {
type.writeDouble(blockBuilder, value.doubleValue());
}
else if (type instanceof RealType) {
type.writeLong(blockBuilder, floatToRawIntBits(value.floatValue()));
}View on GitHub (pinned to 55bb57d202)
Solutions
- Read the embedded errorMessage in the exception text — it is Druid's own reason (e.g. unknown column, timeout) and fix the query accordingly.
- Validate the SQL/datasource by running the query directly against the Druid broker (e.g. curl POST to /druid/v2/sql) to confirm the failure is server-side.
- Check Druid broker logs and query timeout/resource-limit configs (maxScatterGatherBytes, druid.query.timeouts), and raise them if the query is being killed.
- If your table intentionally has a column named errorMessage, note the connector will not treat it as a failure signal; otherwise rename or avoid shadowing the reserved field.
- Refresh Presto's metadata cache (SYSTEM.drop_metadata_cache or restart) if the datasource was recently dropped/recreated.
Example fix
// before: query fails server-side with unclear failure SELECT unknown_col FROM druid.mytable // after: verify the column exists first, or use INFORMATION_SCHEMA SELECT COLUMN_NAME FROM druid.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'mytable'; -- then query only existing columns, e.g. SELECT real_col FROM druid.mytable
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the datasource/columns before querying:
// SELECT COLUMN_NAME FROM druid.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'mytable';
// Ensure every referenced column exists and no query fails server-side.
curl -s -XPOST 'http://druid-broker:8082/druid/v2/sql' \
-H 'Content-Type: application/json' \
-d '{"query":"SELECT 1 FROM mytable LIMIT 1"}' Try / catch
try {
connector.execute(query);
} catch (PrestoException e) {
if (DRUID_BROKER_RESULT_ERROR.toErrorCode().equals(e.getErrorCode())) {
// e.getMessage() is Druid's errorMessage payload — inspect query validity/limits
log.error("Druid query failed server-side: " + e.getMessage(), e);
}
throw e;
} Prevention
- Test queries directly against the Druid broker before running them in Presto
- Verify column names via druid.INFORMATION_SCHEMA.COLUMNS before querying
- Watch Druid broker logs for query failures and limit breaches
- Avoid naming application columns errorMessage to prevent signal shadowing
When it happens
Trigger: Streaming OBJECT_LINES results from DruidBrokerPageSource.getNextPage when any parsed JSON line has a non-null "errorMessage" field and no selected column is named "errorMessage" — i.e. the Druid broker rejected or failed the SQL query mid-stream.
Common situations: Invalid DQL/SQL sent to Druid (unknown column, bad function, syntax error); Druid query timeout or resource limits (maxScatterGatherBytes, query quotas); broker unable to reach historical nodes; Druid version/config changes altering the SQL API; the table or datasource being queried does not exist or segments are unavailable.
Related errors
- DRUID_BROKER_RESULT_ERROR
- DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION
- DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION
- DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION
- INVALID_TABLE_PROPERTY
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/69ea34c97282f282.
Report an issue: GitHub.