Skip to content

Enforce strict trace continuation when starting transactions #1201

Description

@szokeasaurusrex

Implement the strict trace continuation decision when creating transactions. The SDK should reject incoming traces when the incoming sentry-org_id is incompatible with the SDK organization ID according to the spec decision matrix. This is the behavior-changing implementation task for #1016.

Add a CHANGELOG.md entry because this can significantly alter incoming trace continuation behavior.

Implementation notes

Target files:

  • sentry-core/src/performance.rs
  • sentry-actix tests
  • sentry-tower tests
  • CHANGELOG.md

Implementation:

  • In Transaction::new, evaluate the continuation decision before sampling and before constructing protocol::TraceContext.
  • Use:
    • ctx.incoming_org_id
    • client.options().resolved_org_id() when a client exists
    • client.options().strict_trace_continuation
  • Add a private helper such as fn should_continue_trace(incoming: Option<OrganizationId>, sdk: Option<OrganizationId>, strict: bool) -> bool.
  • Decision rules:
    • both IDs present and different -> start a new trace regardless of strict_trace_continuation
    • exactly one ID present -> start a new trace when strict_trace_continuation is true; continue when false
    • both IDs present and equal -> continue
    • both IDs absent -> continue
  • On rejection, replace inbound trace state before sampling:
    • new random/default trace_id
    • parent_span_id: None
    • new/default span_id
    • sampled: None
    • incoming_org_id: None
  • Ensure parent sampling decisions from rejected traces do not influence traces_sampler or ctx.sampled fallback.
  • Preserve existing behavior when there is no active client, since no SDK organization ID or strict option is available.
  • Do not create head-of-trace DSC in this task; that belongs to later DSC work.

Core tests:

  • Cover the full spec matrix for incoming org ID, SDK org ID, and strict_trace_continuation.
  • On rejection, assert the transaction trace ID differs from the incoming trace ID, parent_span_id is None, and parent sampling is not inherited.
  • Assert explicit ClientOptions::org_id overrides the DSN-derived organization ID.

Integration tests:

  • Add actix and tower coverage with the behavior change because these integrations exercise the automatic inbound server path.
  • Use requests with sentry-trace and baggage: sentry-org_id=<id>.
  • With matching org IDs, assert continuation.
  • With mismatched org IDs, assert a new trace is started.

Validation:

  • cargo test -p sentry-core performance
  • cargo test -p sentry-actix
  • cargo test -p sentry-tower

Metadata

Metadata

Assignees

No one assigned

    Labels

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions