{"record":{"id":"9855e5ec95088b38","repo":"apache/seatunnel","slug":"failed-to-execute-http-request-to-s-after-d-atte","errorCode":null,"errorMessage":"Failed to execute HTTP request to %s after %d attempts","messagePattern":"Failed to execute HTTP request to (.+?) after (.+?) attempts","errorType":"exception","errorClass":"SeaTunnelException","httpStatus":null,"severity":"error","filePath":"seatunnel-api/src/main/java/org/apache/seatunnel/api/metalake/gravitino/GravitinoClient.java","lineNumber":175,"sourceCode":"                    }\n                }\n            } catch (IOException e) {\n                if (attempt >= MAX_RETRY_ATTEMPTS) {\n                    break;\n                }\n                // Exponential backoff delay before retry\n                long delayMs = RETRY_DELAY_MS;\n                log.warn(\n                        \"HTTP request to {} failed on attempt {}/{}, retrying in {}ms: {}\",\n                        url,\n                        attempt,\n                        MAX_RETRY_ATTEMPTS,\n                        delayMs,\n                        e.getMessage());\n                sleepQuietly(delayMs);\n            }\n        }\n        throw new SeaTunnelException(\n                String.format(\n                        \"Failed to execute HTTP request to %s after %d attempts\",\n                        url, MAX_RETRY_ATTEMPTS));\n    }\n\n    /** 5xx and 408 and 429 will be retried */\n    private boolean isRetryableHttpStatus(int httpStatus) {\n        return httpStatus == HttpStatus.SC_INTERNAL_SERVER_ERROR\n                || httpStatus == HttpStatus.SC_NOT_IMPLEMENTED\n                || httpStatus == HttpStatus.SC_BAD_GATEWAY\n                || httpStatus == HttpStatus.SC_SERVICE_UNAVAILABLE\n                || httpStatus == HttpStatus.SC_GATEWAY_TIMEOUT\n                || httpStatus == HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED\n                || httpStatus == HttpStatus.SC_INSUFFICIENT_STORAGE\n                || httpStatus == HttpStatus.SC_REQUEST_TIMEOUT\n                || httpStatus == HttpStatus.SC_TOO_MANY_REQUESTS;\n    }\n","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-api/src/main/java/org/apache/seatunnel/api/metalake/gravitino/GravitinoClient.java#L157-L193","documentation":"SeaTunnelException thrown by GravitinoClient.executeGetRequest after exhausting MAX_RETRY_ATTEMPTS on retryable failures (5xx, 408, 429, or IO errors, each with a backoff delay). Indicates persistent unavailability or overload of the Gravitino server.","triggerScenarios":"Calling any read path while the Gravitino server is down, continuously returning 5xx, rate-limiting (429), or timing out (408) for every attempt within the retry budget.","commonSituations":"Gravitino outage or restart loop; server overloaded by many concurrent metadata requests; aggressive rate limiting; long network partition between SeaTunnel and Gravitino.","solutions":["Check Gravitino server health and logs for the period of the failures.","Increase MAX_RETRY_ATTEMPTS/RETRY_DELAY_MS or make them configurable if the outage is expected to be transient.","Reduce concurrent request pressure or add client-side rate limiting to avoid 429s.","Fix underlying network connectivity/DNS issues between the SeaTunnel node and Gravitino."],"exampleFix":"// before\nJsonNode node = client.executeGetRequest(url); // throws after retries\n// after\nfor (int i = 0; i < 3; i++) {\n    try {\n        JsonNode node = client.executeGetRequest(url);\n        break;\n    } catch (SeaTunnelException e) {\n        Thread.sleep(30_000L); // tolerate longer Gravitino outages\n    }\n}","handlingStrategy":"retry","validationCode":"// preflight health probe with retry budget\nfor (int i = 0; i < 3; i++) {\n    HttpURLConnection c = (HttpURLConnection) new URL(gravitinoBaseUri + \"/api/metalakes\").openConnection();\n    c.setConnectTimeout(5000);\n    if (c.getResponseCode() == 200) break;\n    Thread.sleep(5000);\n}","typeGuard":null,"tryCatchPattern":"try {\n    JsonNode node = client.executeGetRequest(url);\n} catch (SeaTunnelException e) {\n    if (e.getMessage().contains(\"after \" + MAX_RETRY_ATTEMPTS + \" attempts\")) {\n        LOG.error(\"Gravitino unavailable after {} retries: {}\", MAX_RETRY_ATTEMPTS, url);\n        // schedule job retry or fail with actionable message\n    }\n    throw e;\n}","preventionTips":["Monitor Gravitino server health and alert before jobs run.","Size retry attempts/delays to tolerate expected transient outages.","Back off client concurrency to avoid triggering 429 rate limits.","Verify network paths/DNS between SeaTunnel workers and Gravitino."],"tags":["retry","http","gravitino","availability","rate-limit"],"backgroundTag":"request-timeout","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"}