Skip to content

oss_10_otlp_partial_success #10

Open

Description

@ocelotl

Tracks OTLP partial-success handling (Linear OSS-10, finding X1).

Problem: OTLP exporters never read the partial_success field, so collector-rejected spans / data points / log records vanish with no log line (silent data loss).

Fix: Deserialize the export response for both transports (gRPC + HTTP) and all three signals (traces, metrics, logs); log a warning with the rejected count / error_message on partial success. Never downgrade a SUCCESS.

Branch / worktree: oss_10_otlp_partial_success

Linear issue: https://linear.app/dash0/issue/OSS-10/x1-otlp-partial-success-responses-ignored-all-signals-both-transports

Activity

  1. ocelotl commented on Jul 22, 2026

    @ocelotl
    OwnerAuthor

    🔒 Internal (dash0) — not for upstream.

    Tracking for the OTLP partial-success fix.

  2. ocelotl commented on Jul 22, 2026

    @ocelotl
    OwnerAuthor

    📣 Public-facing draft — to be opened upstream in open-telemetry/opentelemetry-python. No internal references; copy verbatim.

    Title: OTLP exporters ignore partial_success in export responses (silent data loss)

    Summary

    The OTLP exporters never read the partial_success field of the export response. When a collector accepts an export request but rejects some of the items in it (a partial success — e.g. some spans/data points/log records are dropped due to a resource limit or a bad payload), those rejections are discarded silently: no log line, no metric. Users lose telemetry with no signal that anything went wrong. This affects both transports (gRPC and HTTP/protobuf) and all three signals (traces, metrics, logs).

    Evidence

    • gRPC: OTLPExporterMixin._export calls self._client.Export(...) but does not bind or inspect the return value (exporter/opentelemetry-exporter-otlp-proto-grpc/.../grpc/exporter.py, around the Export(...) call).
    • HTTP: the trace, metric, and log exporters return SUCCESS on resp.ok without deserializing the response body (exporter/opentelemetry-exporter-otlp-proto-http/.../{trace_exporter,metric_exporter,_log_exporter}/__init__.py).
    • A repository-wide grep for partial_success / rejected_ in exporter source returns zero hits.

    Spec

    The OTLP exporter specification (specification/protocol/exporter.md) and the OTLP protocol (docs/specification.md, "Partial Success") require that a client handle partial success: when rejected_spans / rejected_data_points / rejected_log_records is non-zero, or error_message is non-empty, the client SHOULD log the message as a warning. A partial success is still a successful request (the server returned 200/OK), so the export result stays SUCCESS.

    Reference implementations

    Go handles this (exporters/otlp/otlptrace/otlptracegrpc/... and internal/partialsuccess.go). Java's behavior is inconsistent/absent, so Python matching Go here is the right target.

    Proposed fix

    Deserialize the export response for both transports and all three signals. When a rejected count is non-zero or error_message is present, log a warning that includes the rejected count and the message. Keep returning SUCCESS (the request itself was accepted). Guard the deserialization so that an unparseable body cannot turn a successful export into a failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions