pinpoint-apm/pinpoint · error · IOException

OTLP/HTTP request body exceeded max size: limit=${limit}

Error message

OTLP/HTTP request body exceeded max size: limit=${limit}

What it means

OtlpTraceHttpAdmissionFilter guards the RAW (still compressed) request body: the counting stream's add() throws IOException once more than the configured limit bytes have been read. This is a cheap admission-control check that rejects oversized OTLP/HTTP requests before decompression and parsing work is spent.

Source

Thrown at otlptrace/otlptrace-collector/src/main/java/com/navercorp/pinpoint/otlp/trace/collector/controller/OtlpTraceHttpAdmissionFilter.java:194

     * (HTTP 400), bounding heap usage for bodies without a Content-Length.
     */
    private static final class LimitedServletInputStream extends ServletInputStream {
        private final ServletInputStream delegate;
        private final long limit;
        private long count;

        private LimitedServletInputStream(ServletInputStream delegate, long limit) {
            this.delegate = delegate;
            this.limit = limit;
        }

        private void add(int read) throws IOException {
            if (read <= 0) {
                return;
            }
            count += read;
            if (count > limit) {
                throw new IOException("OTLP/HTTP request body exceeded max size: limit=" + limit);
            }
        }

        @Override
        public int read() throws IOException {
            final int b = delegate.read();
            add(b < 0 ? 0 : 1);
            return b;
        }

        @Override
        public int read(byte[] b, int off, int len) throws IOException {
            final int n = delegate.read(b, off, len);
            add(n);
            return n;
        }

        @Override

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Lower the OTLP exporter's max batch/request size so raw request bodies stay under the limit.
  2. Increase the collector's max request body size configuration if legitimate payloads are being rejected.
  3. Compare the client's Content-Length against the collector limit before export; split large exports into multiple requests.
  4. Check proxy/gateway body limits too, since the request may be rejected at any layer.

Example fix

// before
// client sends ~64MB batch; collector limit is 4MB
// after
otlpExporter.setMaxBatchSize(...); // cap so Content-Length < collector limit, or raise collector limit in config
Defensive patterns

Strategy: validation

Validate before calling

if (requestBodyBytes > collectorMaxRequestBodyBytes) {
    throw new IllegalArgumentException("request body " + requestBodyBytes + " exceeds collector limit");
}

Type guard

boolean withinAdmissionLimit(long contentLength, long limit) {
    return contentLength > 0 && contentLength <= limit;
}

Try / catch

try {
    send(exportRequest);
} catch (HttpException e) {
    if (e.status() == 413 || e.getMessage().contains("exceeded max size")) {
        halveBatchAndRetry();
    }
}

Prevention

When it happens

Trigger: POSTing an OTLP/HTTP trace request whose compressed body size exceeds the collector's configured max request body limit; the limit fires while the filter reads the input stream.

Common situations: Client batch size far larger than the server's admission limit; an intermediary (proxy/gateway) also having a smaller body cap; a collector limit was tightened while long-running exporters kept using old large batch settings.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/d26c2187ce38452e. Report an issue: GitHub.