{"record":{"id":"076d19d8fbb9bd6c","repo":"prestodb/presto","slug":"pinot-unauthenticated-exception","errorCode":"PINOT_UNAUTHENTICATED_EXCEPTION","errorMessage":"Query authentication failed.","messagePattern":"Query authentication failed\\.","errorType":"error_code","errorClass":"PinotException","httpStatus":null,"severity":"error","filePath":"presto-pinot-toolkit/src/main/java/com/facebook/presto/pinot/PinotBrokerPageSource.java","lineNumber":291,"sourceCode":"        }\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),\n                String.format(\"Query %s encountered exception %s\", pinotQuery, exceptions.get(0)));\n        }\n    }\n\n    protected static String asText(JsonNode node)\n    {\n        if (node.isArray()) {\n            String[] results = new String[node.size()];\n            for (int i = 0; i < node.size(); i++) {","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-pinot-toolkit/src/main/java/com/facebook/presto/pinot/PinotBrokerPageSource.java#L273-L309","documentation":"Thrown when the Pinot broker response contains an exception entry with errorCode 180, which Pinot uses to signal query authentication failure. The Presto Pinot connector maps that specific error code to this exception so users can distinguish auth problems from other broker-side errors.","triggerScenarios":"handleCommonResponse inspects the 'exceptions' array in the broker response JSON; if exceptions.get(0).get(\"errorCode\").asInt() == 180 the query was rejected because the supplied credentials/token were missing, expired, or invalid for the table.","commonSituations":"Expired access tokens configured in the connector's pinot.auth.token, wrong authentication type configured in Pinot (e.g. TLS auth vs token auth), table-level access control denying the Presto service principal.","solutions":["Verify the auth token configured for the Presto Pinot connector (pinot.auth.token or equivalent config) is present and not expired","Regenerate the token from the Pinot access control config and update the connector properties","Confirm the Pinot cluster's AccessControlFactory is configured and the token type matches (e.g. BasicAuth vs custom)","Test the same token directly against the Pinot broker with curl to isolate whether the problem is Pinot-side or connector-side"],"exampleFix":"// before: connector properties missing or stale token\npinot.auth.token=\n// after: provide a current token\npinot.auth.token=Basic <base64(user:password)>","handlingStrategy":"try-catch","validationCode":"// Validate token presence/config before querying\nif (pinotAuthToken == null || pinotAuthToken.isEmpty()) {\n    throw new IllegalStateException(\"Pinot auth token missing from connector config\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    connector.query(sql);\n} catch (PinotException e) {\n    if (e.getErrorCode() == PinotErrorCode.PINOT_UNAUTHENTICATED_EXCEPTION) {\n        // refresh credentials/token, then retry once\n    }\n    throw e;\n}","preventionTips":["Rotate Pinot auth tokens before expiry and update connector config","Verify the auth type matches the Pinot AccessControlFactory configuration","Test the token directly against the broker before deploying queries"],"tags":["pinot","authentication","access-denied","token"],"backgroundTag":"query-authentication-failed","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"}