OutboxSender sends attachments as standalone envelopes
@markushi 已經在處理了。
開始於 2026年9月16日。
評估
這個 Issue 還沒有評估資料。
描述
What's happening?
When OutboxSender (sentry-java/Android) processes envelopes written to disk by sentry-native (e.g. after an NDK crash), it iterates each envelope item individually. Event and Transaction items go through captureEvent/captureTransaction, but any other item type — including Attachment — is wrapped in a brand-new single-item SentryEnvelope and sent standalone via captureEnvelope, instead of being sent together with the event that produced it.
Why is it happening? (root cause)
This is OutboxSender.processEnvelope in sentry/src/main/java/io/sentry/OutboxSender.java. The loop dispatches Event/Transaction items via their dedicated capture calls, and falls through to a generic else branch for every other item type that wraps that single item in its own envelope and sends it immediately (around OutboxSender.java#L124, current captureEnvelope(newEnvelope, hint) call). There is no step that buffers non-event items and reassembles them into one outgoing envelope keyed by event_id before sending.
Possible solutions (proposal, not yet decided)
- Buffer Attachment-type items encountered while iterating
envelope.getItems(), converting eachSentryEnvelopeIteminto anAttachment(filename/content-type from the item header, bytes fromitem.getData()). - When the Event or Transaction item is found, call
hint.addAttachments(buffered)beforecaptureEvent/captureTransaction, instead of sending each attachment through its owncaptureEnvelopecall.Hintalready supportsaddAttachments(List<Attachment>), so this doesn't require a new envelope format. - Handle item ordering (attachments may appear before or after the event item within the envelope) and the edge case of attachment-only envelopes (no event/transaction present), which must still be sent standalone.
- Add an explicit size check before merging: if attaching would push the combined envelope over the max envelope size, fall back to sending that attachment standalone (or drop it) rather than risking the whole event getting rejected.
- Only merge Attachment-type items — leave other non-event item types (session, user feedback, etc.) on their current per-item send path to avoid changing unrelated behavior.
- Extend
OutboxSenderTest.ktto cover reassembly, mixed item ordering, and the no-event fallback. - Estimated scope: mostly contained to
OutboxSender.javaand its test, no protocol/API changes, no server-side work required — ingestion already accepts combined event+attachment envelopes (used by JS and other SDKs today) and will keep supporting standalone attachments for legacy SDK versions regardless.
User Impact
- Quota/cost impact: Relay has no filter stage for standalone attachments (only
processing/errors/has one), so when an event is dropped by an inbound filter, its standalone attachment still gets ingested and billed — landing as an orphan the customer can't even see, since there's no event to attach it to. Riot Games hit this concretely, ingesting roughly 10TB/day of attachments with ~90% having no associated event, and a live investigation (INGEST-1167) found Android/Java is currently the SDK with the highest volume of standalone attachments. Ingest is shipping a server-side stopgap (discard orphaned attachments at the filter stage), but fixingOutboxSenderremoves the root cause on the Android/Java side rather than relying on ingest to keep mopping up after it. - Mainly affects Android apps using sentry-native (NDK crash reporting) and hybrid SDKs (Unity, Flutter, React Native, etc.) layered on top of sentry-android, since they're the ones writing envelopes to the outbox folder that
OutboxSenderlater fans out.
History of the issue
The design is incidental, not deliberate. The original envelope-pickup code (getsentry/sentry-android#89, getsentry/sentry-android#145, 2019) only handled Event items; every other item type was simply logged as ignored, with a // TODO: Handle attachments and other types comment left in place. In January 2021, getsentry/sentry-java#1158 ("OutboxSender supports all envelope item types") closed that TODO by adding the current catch-all branch: wrap any non-event item in its own envelope and send it immediately. That was a pragmatic fix to stop dropping items, not a considered protocol decision — there's no historical discussion of envelope size limits, item ordering, or ingestion semantics tied to it.
Other useful context
This surfaced from a cross-SDK discussion (also here) about disallowing standalone attachments at the protocol/spec level (develop-docs). Ingestion will keep accepting standalone attachments indefinitely to support already-shipped legacy SDK versions, so this fix is about sentry-java emitting the preferred combined-envelope format going forward, not a breaking or urgent change. If the spec formally disallows standalone attachments before this is fixed, OutboxSender's native-outbox path should get an explicit documented exception until this issue is resolved.
Action taken on behalf of Adam Brown.
- 主要語言
- Kotlin
- 星號
- 1.4k
- 分支
- 478
- 平均合併
- 2 天 20 小時
- 30 天內合併 PR
- 71
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
getsentry/sentry-java 的其他 Issue
-
Improvement Java Platform: Android Platform: Java
難度 2/5 1-3 小時 新手友好度 75/100
getsentry/sentry-java#6145 · 1 則留言 · 已指派 1 人 ·
-
Bug Java Platform: Android Platform: Java
難度 2/5 1-3 小時 新手友好度 78/100
getsentry/sentry-java#6138 · 1 則留言 ·
-
Feature Java Platform: Java Spans
難度 2/5 1-3 小時 新手友好度 68/100
getsentry/sentry-java#5984 · 1 則留言 ·
-
Android Task Traces
難度 2/5 1-3 小時 新手友好度 68/100
getsentry/sentry-java#5376 · 1 則留言 ·
-
Android Docs Errors
難度 2/5 1-3 小時 新手友好度 64/100
getsentry/sentry-java#5375 · 1 則留言 ·
查看 getsentry/sentry-java 的全部 Issue
相似的 Issue
-
enhancement
難度 2/5 1-3 小時 新手友好度 75/100
Richie97/track-history#325 ·
-
bug CLI documentation reliability
難度 2/5 1-3 小時 新手友好度 70/100
-
KW-related Type:bug UI / UX
難度 2/5 1-3 小時 新手友好度 70/100
-
bug
難度 2/5 1-3 小時 新手友好度 75/100
RevenueCat/purchases-android#4299 · 1 則留言 ·
-
bug
難度 2/5 1-3 小時 新手友好度 75/100
AAswordman/Operit#1265 · 3 則留言 ·