{"record":{"id":"d26c2187ce38452e","repo":"pinpoint-apm/pinpoint","slug":"otlp-http-request-body-exceeded-max-size-limit","errorCode":null,"errorMessage":"OTLP/HTTP request body exceeded max size: limit=${limit}","messagePattern":"OTLP/HTTP request body exceeded max size: limit=(.+?)","errorType":"http","errorClass":"IOException","httpStatus":413,"severity":"error","filePath":"otlptrace/otlptrace-collector/src/main/java/com/navercorp/pinpoint/otlp/trace/collector/controller/OtlpTraceHttpAdmissionFilter.java","lineNumber":194,"sourceCode":"     * (HTTP 400), bounding heap usage for bodies without a Content-Length.\n     */\n    private static final class LimitedServletInputStream extends ServletInputStream {\n        private final ServletInputStream delegate;\n        private final long limit;\n        private long count;\n\n        private LimitedServletInputStream(ServletInputStream delegate, long limit) {\n            this.delegate = delegate;\n            this.limit = limit;\n        }\n\n        private void add(int read) throws IOException {\n            if (read <= 0) {\n                return;\n            }\n            count += read;\n            if (count > limit) {\n                throw new IOException(\"OTLP/HTTP request body exceeded max size: limit=\" + limit);\n            }\n        }\n\n        @Override\n        public int read() throws IOException {\n            final int b = delegate.read();\n            add(b < 0 ? 0 : 1);\n            return b;\n        }\n\n        @Override\n        public int read(byte[] b, int off, int len) throws IOException {\n            final int n = delegate.read(b, off, len);\n            add(n);\n            return n;\n        }\n\n        @Override","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/otlptrace/otlptrace-collector/src/main/java/com/navercorp/pinpoint/otlp/trace/collector/controller/OtlpTraceHttpAdmissionFilter.java#L176-L212","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Lower the OTLP exporter's max batch/request size so raw request bodies stay under the limit.","Increase the collector's max request body size configuration if legitimate payloads are being rejected.","Compare the client's Content-Length against the collector limit before export; split large exports into multiple requests.","Check proxy/gateway body limits too, since the request may be rejected at any layer."],"exampleFix":"// before\n// client sends ~64MB batch; collector limit is 4MB\n// after\notlpExporter.setMaxBatchSize(...); // cap so Content-Length < collector limit, or raise collector limit in config","handlingStrategy":"validation","validationCode":"if (requestBodyBytes > collectorMaxRequestBodyBytes) {\n    throw new IllegalArgumentException(\"request body \" + requestBodyBytes + \" exceeds collector limit\");\n}","typeGuard":"boolean withinAdmissionLimit(long contentLength, long limit) {\n    return contentLength > 0 && contentLength <= limit;\n}","tryCatchPattern":"try {\n    send(exportRequest);\n} catch (HttpException e) {\n    if (e.status() == 413 || e.getMessage().contains(\"exceeded max size\")) {\n        halveBatchAndRetry();\n    }\n}","preventionTips":["Cap client-side raw request size below the collector admission limit","Keep proxy/gateway/collector body limits consistent across the path","Emit Content-Length and pre-check it before each export","Re-tune batch sizes whenever the collector limit changes"],"tags":["java","otlp","http","payload-size"],"backgroundTag":"payload-too-large","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}