Skip to content

Enforce OTLP request size limits#8446

Open
ADITYA-CODE-SOURCE wants to merge 5 commits into
open-telemetry:mainfrom
ADITYA-CODE-SOURCE:issue-8444-otlp-message-limits
Open

Enforce OTLP request size limits#8446
ADITYA-CODE-SOURCE wants to merge 5 commits into
open-telemetry:mainfrom
ADITYA-CODE-SOURCE:issue-8444-otlp-message-limits

Conversation

@ADITYA-CODE-SOURCE

Copy link
Copy Markdown
Contributor

Fixes #8444.

Why

  • opentelemetry-proto#782 now recommends that OTLP exporters enforce configurable outbound request/message size limits.
  • OpenTelemetry Java already limits response body reads, but OTLP exporters did not enforce outbound request/message limits.

What

  • add configurable request/message size limits to OTLP HTTP and gRPC exporter builders with a default of 64 MiB
  • enforce the limit in the shared OTLP HTTP and gRPC exporter layers before dispatching requests
  • cover both known-size binary payloads and unknown-size payloads (for example OTLP HTTP JSON) by measuring when needed
  • add focused tests for over-limit failure behavior and builder configuration plumbing
  • update docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt for the new public builder methods

Testing

I was not able to complete local Gradle verification on this Windows machine because Gradle / the Kotlin compiler daemon repeatedly failed to start due to paging-file / metaspace limits before compilation finished. The changes are pushed for CI verification.

@ADITYA-CODE-SOURCE ADITYA-CODE-SOURCE requested a review from a team as a code owner June 3, 2026 03:28
@otelbot otelbot Bot added the api-change Changes to public API surface area label Jun 3, 2026
@otelbot

otelbot Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

⚠️ API changes detected — additional maintainer review required

@jack-berg @jkwatson

This PR modifies the public API surface area of the following module(s):

  • opentelemetry-exporter-otlp

Please review the changes in docs/apidiffs/current_vs_latest/ carefully before approving.

@ADITYA-CODE-SOURCE ADITYA-CODE-SOURCE force-pushed the issue-8444-otlp-message-limits branch from 280870d to 6720aae Compare June 3, 2026 03:30
@ADITYA-CODE-SOURCE

Copy link
Copy Markdown
Contributor Author

@jkwatson Thanks — I pushed a follow-up that fixes the NullAway compile failure in the OTLP internal exporters and applies the naming nits to use constants and public API parameter names.

@jack-berg jack-berg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few small comments, but looks pretty good! Thanks for working on this!

private final boolean exportAsJson;
private final long maxRequestBodySize;

public HttpExporter(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is internal code so we can change the constructor without worrying about breaking any callers. Let's have a single constructor.

public final class HttpExporterBuilder {
public static final long DEFAULT_TIMEOUT_SECS = 10;
public static final long DEFAULT_CONNECT_TIMEOUT_SECS = 10;
public static final long DEFAULT_MAX_REQUEST_BODY_SIZE = Long.MAX_VALUE;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we default to 64mb here? Allows the constant to be defined in once place rather than in each of the exporter builders.

public OtlpGrpcLogRecordExporterBuilder setMaxRequestMessageSize(
long maxRequestMessageSizeBytes) {
checkArgument(
maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting the max body size to 0 is not useful. (Update applies in other places as well)

Suggested change
maxRequestMessageSizeBytes >= 0, "maxRequestMessageSizeBytes must be non-negative");
maxRequestMessageSizeBytes > 0, "maxRequestMessageSizeBytes must be positive");

int contentLength = messageWriter.getContentLength();
if (contentLength >= 0) {
return contentLength;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under what conditions do we pass through this?

My read of the code shows that only Marshaler.toJsonMessageWriter produces a MessageWriter.getContentLength which can return a value <= 0.

I don't know that we can cheaply compute the / enforce the body size for OTLP/json. One more reason not to use it. Officially, we don't support it today. See #5833

@@ -65,15 +86,70 @@ public CompletableResultCode export(Marshaler exportRequest, int numItems) {
exporterMetrics.startRecordingExport(numItems);

CompletableResultCode result = new CompletableResultCode();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since failRequestTooLarge produces its own CompletableResultCode, let's initialize this after line 94.

ExporterInstrumentation.Recording metricRecording,
long requestMessageSize) {
String errorMessage =
"OTLP gRPC request message size "

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep the log message consistent with the shape we use elsewhere in this class when exports fail:

"Failed to export " + type + "s. Request message size " + requestMessageSize + "exceeded limit of " + maxRequestMessageSize + "bytes".

Same advice applies to HttpExporter.

throw new UnsupportedOperationException("Not implemented");
}

default TelemetryExporterBuilder<T> setMaxRequestMessageSize(long maxRequestMessageSize) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No default needed here. This is an internal interface so better to fail loudly with a compile error if an implementation forgot to implement.

exporter.export(Collections.singletonList(generateFakeTelemetry()));

assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse();
Assertions.assertThat(result.getFailureThrowable())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#nit:

Suggested change
Assertions.assertThat(result.getFailureThrowable())
assertThat(result.getFailureThrowable())

Assertions.assertThat(result.getFailureThrowable())
.hasMessageContaining("OTLP gRPC request message size")
.hasMessageContaining("exceeded limit of 1 bytes");
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are test methods in these that verify toString. Should update to assert that the new limit field is included in toString.

@ADITYA-CODE-SOURCE ADITYA-CODE-SOURCE force-pushed the issue-8444-otlp-message-limits branch from afad5b0 to 3cf2f56 Compare June 11, 2026 04:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-change Changes to public API surface area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OTLP exporters should enforce message limits

3 participants