apache/seatunnel · error · HttpConnectorException

REQUEST_FAILED

REQUEST_FAILED

Error message

Stripe PaymentIntents response is not valid JSON

What it means

fetchPage parses the Stripe PaymentIntents HTTP response body with JsonUtils.stringToJsonNode and wraps any parse failure in HttpConnectorException(REQUEST_FAILED). This means the API returned something that is not valid JSON — typically an HTML error page, a proxy/gateway error, or an empty body.

Source

Thrown at seatunnel-connectors-v2/connector-http/connector-http-stripe/src/main/java/org/apache/seatunnel/connectors/seatunnel/stripe/source/StripeSourceReader.java:107

            for (String paymentIntent : page.paymentIntents) {
                output.collect(new SeaTunnelRow(new Object[] {paymentIntent}));
            }
            cursor = page.nextCursor;
        } while (cursor != null);
        context.signalNoMoreElement();
    }

    private StripePage fetchPage(Set<String> seenCursors) throws Exception {
        HttpResponse response = executeWithRateLimitRetry();
        if (response.getCode() < 200 || response.getCode() > 299) {
            throw requestFailed(response);
        }

        JsonNode root;
        try {
            root = JsonUtils.stringToJsonNode(response.getContent());
        } catch (RuntimeException e) {
            throw new HttpConnectorException(
                    HttpConnectorErrorCode.REQUEST_FAILED,
                    "Stripe PaymentIntents response is not valid JSON",
                    e);
        }
        JsonNode dataNode = root.get("data");
        JsonNode hasMoreNode = root.get("has_more");
        if (!(dataNode instanceof ArrayNode) || hasMoreNode == null || !hasMoreNode.isBoolean()) {
            throw new HttpConnectorException(
                    HttpConnectorErrorCode.REQUEST_FAILED,
                    "Stripe PaymentIntents response must contain array 'data' and boolean 'has_more'");
        }

        ArrayNode data = (ArrayNode) dataNode;
        List<String> paymentIntents = new ArrayList<>(data.size());
        String lastId = null;
        for (JsonNode paymentIntent : data) {
            JsonNode idNode = paymentIntent.get("id");
            if (!paymentIntent.isObject()

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Verify api_base_url points at the correct Stripe API host (https://api.stripe.com or valid test mock)
  2. Check for corporate proxies/TLS interception returning HTML error pages and add the proxy's CA or bypass the proxy
  3. Log/inspect the raw response body to confirm what was returned
  4. Retry the job — transient gateway errors (502/503) can produce non-JSON bodies

Example fix

// before
api_base_url = "https://api.stipe.com"  # typo -> HTML/404 page
// after
api_base_url = "https://api.stripe.com"
Defensive patterns

Strategy: try-catch

Try / catch

try { /* fetch */ } catch (HttpConnectorException e) {
  if (e.getHttpConnectorErrorCode() == HttpConnectorErrorCode.REQUEST_FAILED && e.getMessage().contains("not valid JSON")) {
    log.error("Non-JSON body from api_base_url — check URL/proxy/TLS interception");
  }
}

Prevention

When it happens

Trigger: The HTTP response content cannot be parsed as JSON: HTML error pages from misconfigured api_base_url, gateway 502/503 pages, proxies injecting content, or empty responses.

Common situations: api_base_url pointing to a non-Stripe host or a captive corporate proxy; TLS-intercepting firewalls returning HTML; Stripe outage page; local mock server returning malformed JSON.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/d33feb0edde34e83. Report an issue: GitHub.