{"record":{"id":"d0d724a0d672a712","repo":"prestodb/presto","slug":"pinot-insufficient-server-response","errorCode":"PINOT_INSUFFICIENT_SERVER_RESPONSE","errorMessage":"Only %s out of %s servers responded for query %s","messagePattern":"Only (.+?) out of (.+?) servers responded for query (.+?)","errorType":"error_code","errorClass":"PinotException","httpStatus":null,"severity":"error","filePath":"presto-pinot-toolkit/src/main/java/com/facebook/presto/pinot/PinotBrokerPageSource.java","lineNumber":282,"sourceCode":"            if (result == null || result.size() < blockBuilders.size()) {\n                throw new PinotException(\n                    PINOT_UNEXPECTED_RESPONSE,\n                    Optional.of(query),\n                    String.format(\"Expected row of %d columns\", blockBuilders.size()));\n            }\n            for (int columnNumber = 0; columnNumber < blockBuilders.size(); columnNumber++) {\n                setValue(types.get(columnNumber), blockBuilders.get(columnNumber), result.get(columnNumber));\n            }\n        }\n    }\n\n    protected static void handleCommonResponse(String pinotQuery, JsonNode jsonBody)\n    {\n        JsonNode numServersResponded = jsonBody.get(\"numServersResponded\");\n        JsonNode numServersQueried = jsonBody.get(\"numServersQueried\");\n\n        if (numServersQueried == null || numServersResponded == null || numServersQueried.asInt() > numServersResponded.asInt()) {\n            throw new PinotException(\n                PINOT_INSUFFICIENT_SERVER_RESPONSE,\n                Optional.of(pinotQuery),\n                String.format(\"Only %s out of %s servers responded for query %s\", numServersResponded.asInt(), numServersQueried.asInt(), pinotQuery));\n        }\n\n        JsonNode exceptions = jsonBody.get(\"exceptions\");\n        if (exceptions != null && exceptions.isArray() && exceptions.size() > 0) {\n            if (exceptions.get(0).get(\"errorCode\").asInt() == 180) {\n                throw new PinotException(\n                    PINOT_UNAUTHENTICATED_EXCEPTION,\n                    Optional.empty(),\n                    \"Query authentication failed.\");\n            }\n            // Pinot is known to return exceptions with benign errorcodes like 200\n            // so we treat any exception as an error\n            throw new PinotException(\n                PINOT_EXCEPTION,\n                Optional.of(pinotQuery),","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-pinot-toolkit/src/main/java/com/facebook/presto/pinot/PinotBrokerPageSource.java#L264-L300","documentation":"Thrown when a Pinot broker query response reports fewer servers responded (numServersResponded) than servers queried (numServersQueried), meaning some Pinot servers failed to answer the query. The Presto Pinot connector treats partial responses as untrustworthy results and fails the query rather than returning incomplete data.","triggerScenarios":"handleCommonResponse is called from populateFromQueryResults after parsing the broker response JSON; it throws when numServersQueried or numServersResponded is missing from the response body, or numServersQueried > numServersResponded (e.g. some Pinot servers timed out, crashed, or were restarted mid-query).","commonSituations":"Pinot server timeouts on heavy queries, a server being restarted or OOM-killed during a query, network partitions between broker and servers, oversized segment scans exceeding server timeouts.","solutions":["Check Pinot server logs for the servers that did not respond; look for timeouts, GC pauses, or crashes during the query window","Reduce query cost (add selective filters, limit columns, use LIMIT) so servers respond within the timeout","Increase Pinot server/broker timeouts (query.timeoutMs on broker, server timeout configs) via Pinot cluster config","Retry the query; transient server restarts often resolve on a second attempt","Verify Pinot cluster health (all servers up, segment replication adequate) before rerunning the query"],"exampleFix":"// before: query scans a large table with no filter, servers time out\nSELECT * FROM myTable WHERE ts > 0\n// after: constrain the query so all servers respond in time\nSELECT colA, colB FROM myTable WHERE ts BETWEEN '2024-01-01' AND '2024-01-02' LIMIT 1000","handlingStrategy":"retry","validationCode":"// No pre-call check possible; check Pinot cluster health before query\n// e.g. verify all Pinot servers are live via controller /health or cluster state","typeGuard":null,"tryCatchPattern":"try {\n    connector.query(sql);\n} catch (PinotException e) {\n    if (e.getErrorCode() == PinotErrorCode.PINOT_INSUFFICIENT_SERVER_RESPONSE) {\n        // wait/backoff then retry; alert if persistent\n    }\n}","preventionTips":["Keep Pinot queries selective so servers finish within timeouts","Monitor Pinot server restarts and GC pauses","Set adequate broker/server query timeouts for your workload","Ensure enough segment replicas so a down server doesn't guarantee partial results"],"tags":["pinot","distributed-query","timeout","partial-response"],"backgroundTag":"partial-query-response","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}