{"record":{"id":"68841c57cc924bce","repo":"apache/seatunnel","slug":"failed-to-send-airtable-api-request","errorCode":null,"errorMessage":"Failed to send Airtable API request","messagePattern":"Failed to send Airtable API request","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-http/connector-http-airtable/src/main/java/org/apache/seatunnel/connectors/seatunnel/airtable/sink/AirtableSinkWriter.java","lineNumber":158,"sourceCode":"                            retryCount,\n                            rateLimitMaxRetries,\n                            backoffMillis);\n                    try {\n                        Thread.sleep(backoffMillis);\n                    } catch (InterruptedException e) {\n                        Thread.currentThread().interrupt();\n                        throw new RuntimeException(e);\n                    }\n                    continue;\n                }\n                throw new IOException(\n                        String.format(\n                                \"Airtable API request failed, status code:[%s], content:[%s]\",\n                                response.getCode(), response.getContent()));\n            } catch (IOException e) {\n                throw e;\n            } catch (Exception e) {\n                throw new IOException(\"Failed to send Airtable API request\", e);\n            }\n        }\n    }\n\n    private void waitForRequestSlot() {\n        if (requestIntervalMs <= 0) {\n            return;\n        }\n        long now = System.currentTimeMillis();\n        long elapsed = now - lastRequestTimeMillis;\n        if (elapsed < requestIntervalMs) {\n            try {\n                Thread.sleep(requestIntervalMs - elapsed);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n                throw new RuntimeException(e);\n            }\n        }","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-http/connector-http-airtable/src/main/java/org/apache/seatunnel/connectors/seatunnel/airtable/sink/AirtableSinkWriter.java#L140-L176","documentation":"sendWithRateLimitRetry wraps any non-IOException failure while executing the Airtable HTTP request into an IOException with message 'Failed to send Airtable API request' and the original as cause. This covers client-side errors (connection failures, timeouts, serialization issues) rather than Airtable-returned error statuses.","triggerScenarios":"The HTTP client call itself throws a non-IO exception: DNS/connect failures surfaced as runtime exceptions, SSL handshake errors, request building failures, or interruptions during the HTTP call.","commonSituations":"Network outages or firewall blocking airtable.com from the SeaTunnel worker, TLS/proxy misconfiguration, or hostname resolution failures in containers.","solutions":["Inspect the cause chain for the root exception (UnknownHostException, SSLException, ConnectException).","Verify network/DNS/proxy connectivity from the SeaTunnel worker node to api.airtable.com:443.","Fix proxy settings (-Dhttps.proxyHost/-Dhttps.proxyPort) if behind a corporate proxy.","Retry the job once connectivity is restored; the writer is checkpoint-aware so it will resume."],"exampleFix":"// before: worker has no egress to api.airtable.com\n// after: set JVM proxy args on the worker\n-Dhttps.proxyHost=proxy.corp.internal -Dhttps.proxyPort=3128","handlingStrategy":"try-catch","validationCode":"// From the worker node before running\ncurl -sS --max-time 5 https://api.airtable.com/v0/meta/whoami -H \"Authorization: Bearer $AIRTABLE_TOKEN\"","typeGuard":null,"tryCatchPattern":"try { writer.write(row); } catch (IOException e) { if (getRootCause(e) instanceof java.net.ConnectException || getRootCause(e) instanceof java.net.UnknownHostException) { /* check network/proxy */ } }","preventionTips":["Verify egress to api.airtable.com:443 from workers","Configure JVM proxy properties in containerized/VPN networks","Check DNS resolution inside the cluster"],"tags":["network","http","airtable"],"backgroundTag":"network-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"}