apache/pulsar · warning · IOException

HTTP response body exceeds the configured maximum of ${confi

Error message

HTTP response body exceeds the configured maximum of ${config.maxResponseBodyBytes} bytes

What it means

FrameworkHttpClient's handler accumulates response body bytes in onBodyPartReceived and throws IOException as soon as the running total exceeds config.maxResponseBodyBytes(). This stream-limit guard prevents unbounded memory use from oversized OAuth2/IdP responses. Once tripped, the whole response is aborted.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/v5/FrameworkHttpClient.java:118

     * {@code onBodyPartReceived} aborts the connection and completes the future exceptionally, so the cap
     * bounds memory rather than being checked after full aggregation.
     */
    private final class BoundedResponseHandler extends AsyncCompletionHandlerBase {
        private long receivedBytes;

        @Override
        public State onStatusReceived(HttpResponseStatus status) throws Exception {
            // A new response on this exchange restarts the accumulation, so each response of a redirect
            // chain is bounded independently (matching the builder reset in the superclass).
            receivedBytes = 0;
            return super.onStatusReceived(status);
        }

        @Override
        public State onBodyPartReceived(HttpResponseBodyPart content) throws Exception {
            receivedBytes += content.length();
            if (receivedBytes > config.maxResponseBodyBytes()) {
                throw new IOException("HTTP response body exceeds the configured maximum of "
                        + config.maxResponseBodyBytes() + " bytes");
            }
            return super.onBodyPartReceived(content);
        }
    }

    private org.asynchttpclient.Request toAhcRequest(HttpRequest request) {
        RequestBuilder builder = new RequestBuilder(request.method().name())
                .setUrl(request.uri().toString());
        if (nameResolver != null) {
            // Share the DNS resolver and its cache with the owning PulsarClient.
            builder.setNameResolver(nameResolver);
        }

        request.headers().forEach(builder::setHeader);

        request.body().ifPresent(body -> {
            if (body instanceof HttpRequest.Bytes bytes) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Increase config.maxResponseBodyBytes() to comfortably exceed the expected response size (metadata docs are usually a few KB).
  2. Verify what the endpoint actually returns (curl it) — a giant HTML error page means fix the URL/routing instead.
  3. Check for proxies/interceptors injecting large bodies into the response.
  4. If the response is legitimately huge, consider whether the IdP is misconfigured (e.g. leaking keys repeatedly).

Example fix

// before
FrameworkHttpConfig config = FrameworkHttpConfig.builder().maxResponseBodyBytes(1024).build(); // too small
// after
FrameworkHttpConfig config = FrameworkHttpConfig.builder().maxResponseBodyBytes(1024 * 1024).build(); // 1 MiB
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity-check expected response size before configuring the limit
String body = HttpClient.newHttpClient().send(
    HttpRequest.newBuilder(URI.create(issuerUrl + "/.well-known/openid-configuration")).GET().build(),
    HttpResponse.BodyHandlers.ofString()).body();
long minLimit = body.getBytes(java.nio.charset.StandardCharsets.UTF_8).length * 4; // headroom
if (maxResponseBodyBytes < minLimit) throw new IllegalStateException("Raise maxResponseBodyBytes");

Try / catch

try {
    client = AuthenticationFactoryOAuth2.clientCredentials(issuerUrl, credFile, audience);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().contains("exceeds the configured maximum")) {
        throw new RuntimeException("Response exceeded maxResponseBodyBytes — raise the limit or fix the endpoint returning oversized bodies", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Any HTTP response from the IdP whose body exceeds the configured maximum — e.g. an unexpectedly huge discovery metadata document, an error page dumped as HTML, a misbehaving gateway streaming endless data, or maxResponseBodyBytes configured too small for a legitimately large response.

Common situations: Lowering maxResponseBodyBytes below the real discovery-document size; IdP misconfiguration returning giant HTML error pages; intermediary/proxy injecting large content; legitimate but large JWKS/metadata responses after tenant/key growth.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/acf79368de663200. Report an issue: GitHub.