Overview
The DataCollection spec replaces the binary SendDefaultPii flag with a structured DataCollection option that gives users per-category control over automatically collected data:
UserInfo (id/email/username/ip) — default true
Cookies, HttpHeaders (request/response), UrlQueryParams — key-value collection behavior: off / denyList (default) / allowList over a canonical sensitive-terms denylist, values replaced with [Filtered]
HttpBodies — which of the four directions (incoming/outgoing × request/response) to attach
GraphQL (document/variables), GenAI (inputs/outputs), DatabaseQueryData, Queues, StackFrameVariables, FrameContextLines
Reference implementation: sentry-javascript, tracked in getsentry/sentry-javascript#20141 (foundation PR getsentry/sentry-javascript#20965). JS shipped the entire migration in v10 minor releases with zero behavior changes for existing users; removal of sendDefaultPii is deferred to their next major.
Strategy
Following the JS playbook:
- Resolve once, read everywhere:
DataCollection is resolved to an internal fully-populated config at SDK init; all consumers read only the resolved object.
- Bridge: when
DataCollection is not set, the resolved config is derived from SendDefaultPii (true → everything on; false/unset → restrictive + GDPR deny-terms). If both are set, SendDefaultPii is ignored.
- New permissive defaults (user identity and HTTP bodies collected by default) apply only when the user explicitly sets
DataCollection — nobody's behavior changes until the next major.
- User-set data is never gated (e.g. an explicitly set
User); DataCollection only gates automatic collection.
- Integration-level options take precedence over the global
DataCollection layer (e.g. MaxRequestBodySize, SentryAIOptions.RecordInputs).
- Every PR is independently shippable and behavior-neutral. Phase 0 tightens default privacy with no new API and is useful standalone.
Phases
Phase 0 — Hardening pre-work (no new API, each independently useful)
Phase 1 — Foundation (option is a documented no-op after this)
Phase 2 — Consumer migrations (behavior-neutral, one PR per area)
Phase 3 — Deprecation (minor)
Phase 4 — Defaults flip (minor, only for explicit DataCollection users)
Phase 5 — Next major
.NET-specific notes
- Native propagation: until sentry-java / sentry-cocoa implement the spec, the resolved config is down-converted to the native
sendDefaultPii boolean (conservatively).
- Config binding: the option shape must bind from
appsettings.json (BindableSentryOptions and friends) — a requirement JS didn't have.
[Obsolete] timing: unlike JSDoc @deprecated, [Obsolete] produces compiler warnings that break TreatWarningsAsErrors builds. Docs/changelog deprecation lands in a minor; attribute timing to be decided (see the deprecation sub-issue).
- Spec categories .NET can't act on yet (
Queues — no queue integration captures args; StackFrameVariables / FrameContextLines — native-layer only): included in the option shape from day one and forwarded to native where relevant. JS added graphQL/databaseQueryData late and had to re-gate integrations (getsentry/sentry-javascript#22219) and rename queryParams → urlQueryParams (getsentry/sentry-javascript#22217) — we use final spec names from the start.
- Docs work (options page, migration guide, "data collected" pages) is tracked separately in sentry-docs.
Overview
The DataCollection spec replaces the binary
SendDefaultPiiflag with a structuredDataCollectionoption that gives users per-category control over automatically collected data:UserInfo(id/email/username/ip) — defaulttrueCookies,HttpHeaders(request/response),UrlQueryParams— key-value collection behavior:off/denyList(default) /allowListover a canonical sensitive-terms denylist, values replaced with[Filtered]HttpBodies— which of the four directions (incoming/outgoing × request/response) to attachGraphQL(document/variables),GenAI(inputs/outputs),DatabaseQueryData,Queues,StackFrameVariables,FrameContextLinesReference implementation: sentry-javascript, tracked in getsentry/sentry-javascript#20141 (foundation PR getsentry/sentry-javascript#20965). JS shipped the entire migration in v10 minor releases with zero behavior changes for existing users; removal of
sendDefaultPiiis deferred to their next major.Strategy
Following the JS playbook:
DataCollectionis resolved to an internal fully-populated config at SDK init; all consumers read only the resolved object.DataCollectionis not set, the resolved config is derived fromSendDefaultPii(true→ everything on;false/unset → restrictive + GDPR deny-terms). If both are set,SendDefaultPiiis ignored.DataCollection— nobody's behavior changes until the next major.User);DataCollectiononly gates automatic collection.DataCollectionlayer (e.g.MaxRequestBodySize,SentryAIOptions.RecordInputs).Phases
Phase 0 — Hardening pre-work (no new API, each independently useful)
Phase 1 — Foundation (option is a documented no-op after this)
Phase 2 — Consumer migrations (behavior-neutral, one PR per area)
Phase 3 — Deprecation (minor)
Phase 4 — Defaults flip (minor, only for explicit DataCollection users)
Phase 5 — Next major
.NET-specific notes
sendDefaultPiiboolean (conservatively).appsettings.json(BindableSentryOptionsand friends) — a requirement JS didn't have.[Obsolete]timing: unlike JSDoc@deprecated,[Obsolete]produces compiler warnings that breakTreatWarningsAsErrorsbuilds. Docs/changelog deprecation lands in a minor; attribute timing to be decided (see the deprecation sub-issue).Queues— no queue integration captures args;StackFrameVariables/FrameContextLines— native-layer only): included in the option shape from day one and forwarded to native where relevant. JS addedgraphQL/databaseQueryDatalate and had to re-gate integrations (getsentry/sentry-javascript#22219) and renamequeryParams→urlQueryParams(getsentry/sentry-javascript#22217) — we use final spec names from the start.