apache/seatunnel · error · IOException
Airtable API request failed, status code
Error message
Airtable API request failed, status code:[%s], content:[%s]
What it means
AirtableSinkWriter.sendWithRateLimitRetry throws this IOException when the Airtable HTTP API returns a non-success, non-rate-limit status code. The message embeds the HTTP status and response body so you can see exactly why Airtable rejected the request (auth, bad table id, invalid payload, etc.).
Solutions
- Read the status code and content in the message: 401/403 → fix the Airtable API token and its scopes; 404 → correct baseId/tableId.
- For 422, align the SeaTunnel row fields/types with the Airtable table columns.
- Retry after transient 5xx; check https://status.airtable.com for outages.
- Increase or respect rate limiting so requests aren't rejected.
Example fix
// before: sink config with bad table id baseId = appXXXXXXXXXXXX tableId = WrongTable // after baseId = appXXXXXXXXXXXX tableId = tblRealTableId (copied from Airtable API docs URL)
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check before running the job
curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $AIRTABLE_TOKEN" "https://api.airtable.com/v0/$BASE_ID/$TABLE_ID?maxRecords=1" # expect 200 Try / catch
try { sinkWriter.prepareCommit(); } catch (RuntimeException e) { /* inspect cause IOException message for status code/content */ } Prevention
- Validate token and scopes with a test API call
- Copy baseId/tableId directly from the Airtable API URL
- Match row fields to the table schema
- Monitor https://status.airtable.com
When it happens
Trigger: Any Airtable API response with an error status that was not retried as 429: e.g. 401 invalid token, 403 forbidden, 404 unknown base/table, 422 invalid field value in the record payload.
Common situations: Expired or wrong personal access token, typo'd baseId/tableId in sink config, writing a record whose fields don't match the Airtable table schema, or Airtable-side outages returning 5xx.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Failed to send Airtable API request
- Firebase HTTP request failed with status code
- REQUEST_FAILED
- ADD_FIELD_FAILED
- Airtable API rate limit reached, retry
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/f3c8ae905635c64a.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-http/connector-http-airtable/src/main/java/org/apache/seatunnel/connectors/seatunnel/airtable/sink/AirtableSinkWriter.java:151
}
if (response.getCode() == STATUS_TOO_MANY_REQUESTS
&& retryCount < rateLimitMaxRetries) {
retryCount++;
long backoffMillis = calculateBackoffMillis(retryCount);
log.warn(
"Airtable API rate limit reached, retry {}/{} after {} ms",
retryCount,
rateLimitMaxRetries,
backoffMillis);
try {
Thread.sleep(backoffMillis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
continue;
}
throw new IOException(
String.format(
"Airtable API request failed, status code:[%s], content:[%s]",
response.getCode(), response.getContent()));
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException("Failed to send Airtable API request", e);
}
}
}
private void waitForRequestSlot() {
if (requestIntervalMs <= 0) {
return;
}
long now = System.currentTimeMillis();
long elapsed = now - lastRequestTimeMillis;
if (elapsed < requestIntervalMs) {View on GitHub (pinned to cf67b549a7)