{"record":{"id":"ac59488986f12928","repo":"apache/seatunnel","slug":"quest-query-plan-failed","errorCode":"QUEST_QUERY_PLAN_FAILED","errorMessage":"query failed with empty response","messagePattern":"query failed with empty response","errorType":"error_code","errorClass":"StarRocksConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-starrocks/src/main/java/org/apache/seatunnel/connectors/seatunnel/starrocks/client/source/StarRocksQueryPlanReadClient.java","lineNumber":174,"sourceCode":"                            .append(sourceConfig.getDatabase())\n                            .append(\"/\")\n                            .append(table)\n                            .append(\"/_query_plan\")\n                            .toString();\n            try {\n                respString =\n                        RetryUtils.retryWithException(\n                                () -> httpHelper.doHttpPost(url, getQueryPlanHttpHeader(), body),\n                                retryMaterial);\n                if (StringUtils.isNoneEmpty(respString)) {\n                    return JsonUtils.parseObject(respString, QueryPlan.class);\n                }\n            } catch (Exception e) {\n                log.error(\"Request query Plan From {} failed: {}\", feNode, e.getMessage());\n            }\n        }\n\n        throw new StarRocksConnectorException(\n                StarRocksConnectorErrorCode.QUEST_QUERY_PLAN_FAILED,\n                \"query failed with empty response\");\n    }\n\n    private String getBasicAuthHeader(String username, String password) {\n        String auth = username + \":\" + password;\n        byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8));\n        return new StringBuilder(\"Basic \").append(new String(encodedAuth)).toString();\n    }\n\n    private Map<String, String> getQueryPlanHttpHeader() {\n        Map<String, String> headerMap = new HashMap<>();\n        headerMap.put(\"Content-Type\", \"application/json;charset=UTF-8\");\n        headerMap.put(\n                \"Authorization\",\n                getBasicAuthHeader(sourceConfig.getUsername(), sourceConfig.getPassword()));\n        return headerMap;\n    }","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-starrocks/src/main/java/org/apache/seatunnel/connectors/seatunnel/starrocks/client/source/StarRocksQueryPlanReadClient.java#L156-L192","documentation":"StarRocksSource's query plan client fetches an HTTP query plan from a StarRocks FE node; after exhausting all configured FE nodes (each attempt caught and logged), it throws QUEST_QUERY_PLAN_FAILED with 'query failed with empty response'. This means no FE returned a usable query plan, so no splits can be produced and the source read fails.","triggerScenarios":"All FE HTTP endpoints fail during queryPlan(): FE unreachable/wrong port (default 8030 http vs 9030 mysql), wrong username/password, query plan HTTP call returning non-200 or empty body, or network/firewall blocking the FE HTTP port.","commonSituations":"cluster.query_url pointing at FE RPC port instead of HTTP port; FE nodes down or behind a LB dropping the request; auth failure against FE; Kerberos/HTTP auth setup differences; containerized deployments where FE hostname is not resolvable from the SeaTunnel worker.","solutions":["Verify cluster FE HTTP port (usually 8030) is reachable from the SeaTunnel node: curl -u user:pass http://<fe>:8030/api/<db>/<table>/_query_plan","Check fe.log on the StarRocks FE for the failed plan request and its root cause","Confirm username/password are correct and the user has SELECT privilege on the table","If multiple FEs are configured, ensure at least one is healthy; check network/DNS and firewall rules","Retry the job — transient FE restarts or load can cause all-attempt failures"],"exampleFix":"// before\nurl = \"http://fe-host:9030/api/db/table/_query_plan\" // wrong port (mysql port)\n// after\nurl = \"http://fe-host:8030/api/db/table/_query_plan\"","handlingStrategy":"retry","validationCode":"curl -s -u user:pass http://fe-host:8030/api/db/table/_query_plan -X POST -d '{}' # verify FE plan endpoint reachable before running the job","typeGuard":"boolean feReachable(String feUrl) { try { HttpURLConnection c = (HttpURLConnection) new URL(feUrl).openConnection(); c.setConnectTimeout(3000); return c.getResponseCode() > 0; } catch (Exception e) { return false; } }","tryCatchPattern":"try { runJob(); } catch (StarRocksConnectorException e) { if (Objects.equals(e.getErrorCode(), StarRocksConnectorErrorCode.QUEST_QUERY_PLAN_FAILED)) { /* check FE health, retry with backoff or fail fast with FE diagnostics */ } throw e; }","preventionTips":["Point query URL at the FE HTTP port (8030), not the MySQL query port (9030)","Health-check all FE nodes before job submission","Grant the configured user SELECT privileges and correct password","Monitor fe.log for _query_plan request failures"],"tags":["starrocks","network","http","source"],"backgroundTag":"http-request-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}