Skip to content

feat!: Replace deprecated http.* span attributes on HTTP spans - #23423

Closed
msonnb wants to merge 1 commit into
developfrom
ms/deprecated-http-net-attributes
Closed

msonnb wants to merge 1 commit into
developfrom
ms/deprecated-http-net-attributes

Conversation

@msonnb

@msonnb msonnb commented Aug 13, 2026

Copy link
Copy Markdown
Member

Replaces the http.* span attributes @sentry/conventions marks deprecated.

Straight renames

  • http.method -> http.request.method
  • http.status_code -> http.response.status_code
  • http.scheme -> url.scheme
  • http.user_agent -> user_agent.original
  • http.response_content_length -> http.response.body.size
  • http.response_transfer_size -> http.response.size
  • url.same_origin -> http.request.same_origin

http.request_content_length, http.request_content_length_uncompressed, http.response_content_length_uncompressed and http.status_text are left alone. They are not in @sentry/conventions at all, so they have no replacement to move to.

Changes that are not renames

http.host, http.flavor and http.client_ip

These are dropped without a replacement being set here. Their replacements server.address, network.protocol.version and client.address are introduced by #23301 as part of the net.* alignment.

url.query and url.fragment on core server spans

http.target held the pathname and the query. url.path holds only the pathname.

The server span in @sentry/core set neither url.query nor url.fragment. Dropping http.target would therefore have lost the query. That span now sets both. The server span in @sentry/node already set both.

Consumers that matched on http.target

Two ignoreSpans rules match spans that the SDK itself emits. Both now match on url.path:

  • the low-quality transaction filter in @sentry/react-router
  • the tunnel-route filter in @sentry/tanstackstart-react

The readers in @sentry/nextjs still read http.target, but only after they read url.path. These readers also receive spans from an OpenTelemetry instrumentation that the user set up, and that instrumentation still emits the old attributes. Every other read-side fallback stays for the same reason.

SanitizedRequestData

This type is the shape of http breadcrumb data. It now uses http.request.method as the key for the request method.

no-unfiltered-url-attributes

This lint rule no longer guards http.target. The SDK no longer sets http.target. Its replacement url.path holds a pathname without a query, so there is nothing to filter.

part of #18895

@msonnb

msonnb commented Aug 13, 2026

Copy link
Copy Markdown
Member Author

bugbot run

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 28.57 kB - -
@sentry/browser - with treeshaking flags 26.92 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 26.82 kB - -
@sentry/browser (incl. Tracing) 48.5 kB +0.01% +3 B 🔺
@sentry/browser (incl. Tracing + Span Streaming) 48.52 kB -0.02% -8 B 🔽
@sentry/browser (incl. Tracing, Profiling) 51.42 kB -0.01% -3 B 🔽
@sentry/browser (incl. Tracing, Replay) 87.88 kB -0.02% -9 B 🔽
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 77.34 kB -0.02% -10 B 🔽
@sentry/browser (incl. Tracing, Replay with Canvas) 92.58 kB -0.01% -8 B 🔽
@sentry/browser (incl. Tracing, Replay, Feedback) 105.3 kB +0.01% +3 B 🔺
@sentry/browser (incl. Feedback) 45.81 kB - -
@sentry/browser (incl. sendFeedback) 33.36 kB - -
@sentry/browser (incl. FeedbackAsync) 38.47 kB - -
@sentry/browser (incl. Metrics) 29.52 kB - -
@sentry/browser (incl. Logs) 29.8 kB - -
@sentry/browser (incl. Metrics & Logs) 30.45 kB - -
@sentry/react 30.33 kB - -
@sentry/react (incl. Tracing) 50.7 kB -0.02% -7 B 🔽
@sentry/vue 35.64 kB - -
@sentry/vue (incl. Tracing) 50.72 kB -0.04% -18 B 🔽
@sentry/svelte 28.6 kB - -
CDN Bundle 30.32 kB - -
CDN Bundle (incl. Tracing) 49.02 kB -0.02% -7 B 🔽
CDN Bundle (incl. Logs, Metrics) 32.54 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 50.9 kB +0.02% +6 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 72.91 kB - -
CDN Bundle (incl. Tracing, Replay) 86.47 kB +0.01% +5 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 88.33 kB -0.01% -2 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) 92.24 kB +0.02% +15 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 94.17 kB - -
CDN Bundle - uncompressed 89.94 kB - -
CDN Bundle (incl. Tracing) - uncompressed 146.59 kB -0.04% -55 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed 96.23 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 152.28 kB -0.04% -55 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 225.18 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 265.87 kB -0.03% -55 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 271.54 kB -0.03% -55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 279.56 kB -0.02% -55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 285.23 kB -0.02% -55 B 🔽
@sentry/nextjs (client) 53.24 kB +0.03% +13 B 🔺
@sentry/sveltekit (client) 48.92 kB +0.01% +4 B 🔺
@sentry/core/server 64.97 kB -0.22% -140 B 🔽
@sentry/core/browser 52.29 kB +0.05% +26 B 🔺
@sentry/node 121.39 kB -0.3% -357 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection) 85.18 kB - -
@sentry/node - without tracing 87.45 kB -0.12% -103 B 🔽
@sentry/aws-serverless 95.59 kB -0.4% -377 B 🔽
@sentry/cloudflare (withSentry) - minified 196.91 kB +0.01% +13 B 🔺
@sentry/cloudflare (withSentry) 487.49 kB +0.01% +20 B 🔺

View base workflow run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 701694c. Configure here.

return { hostname: match[1], port: port <= 65535 ? port : undefined };
}
return { hostname: host || 'localhost', port: undefined };
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Host header parser mishandles IPv6

Medium Severity

splitHostHeader splits on the last : plus digits, so an IPv6 Host value such as [::1]:8080 keeps the brackets in server.address, and a missing header becomes localhost. Both values are wrong for server.address on every incoming server span.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 701694c. Configure here.

// `Host` header land on `server.address`; the header wins when both are set.
// `url.path`, `url.query` and `http.request.method` come from `attributes` below, which is why
// the old `http.target` (path plus query) has no separate replacement here.
[SERVER_ADDRESS]: request.getHeader('host') ?? request.host,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Client spans embed port in address

Medium Severity

Outgoing HTTP spans copy the Host header or URL.host into server.address, so the port stays in the address and server.port is never set. Server spans already split those with splitHostHeader. Client traces therefore disagree with the server spans and with the server.* spec.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 701694c. Configure here.

'network.local.port': expect.any(Number),
'network.peer.address': expect.any(String),
'server.port': expect.any(Number),
'http.response.status_code': 200,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

E2E tests remap peer port wrongly

High Severity

These toEqual payloads list server.address twice and map net.peer.port to server.port. The second key wins, so the Host-header address is never asserted, and the extra network.peer.port the SDK still emits makes the strict equality fail. I flagged this because the testing conventions in the review rules require tests to assert the new attributes thoroughly.

Additional Locations (2)
Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 701694c. Configure here.

return (
transactionEvent.contexts?.trace?.data?.['http.target'] === `/generation-functions?metadataTitle=${testTitle}`
);
return transactionEvent.contexts?.trace?.data?.['url.path'] === `/generation-functions?metadataTitle=${testTitle}`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Tests match query on url.path

High Severity

waitForTransaction and the Next.js 15 tracesSampler now compare url.path to a string that still includes the query. url.path is pathname-only; http.target used to carry path plus query. Those waiters never match, so the tests time out. I flagged this because the testing conventions in the review rules require tests to cover the new attributes correctly.

Additional Locations (2)
Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 701694c. Configure here.

@msonnb
msonnb force-pushed the ms/deprecated-http-net-attributes branch from 71a94a4 to afc9274 Compare August 24, 2026 08:35
@msonnb msonnb changed the title ref(core)!: Replace deprecated http.* and net.* span attributes on HTTPS spans ref(core)!: Replace deprecated http.* span attributes on HTTP spans Aug 24, 2026
@msonnb
msonnb force-pushed the ms/deprecated-http-net-attributes branch 3 times, most recently from 5177d40 to 743aa06 Compare August 24, 2026 13:25
Part of the v11 migration away from attributes `@sentry/conventions` marks
deprecated. Scoped to the `http.*` attributes on HTTP spans; the `net.*`
attributes are migrated separately in #23301.

Straight renames: `http.method` -> `http.request.method`, `http.status_code` ->
`http.response.status_code`, `http.scheme` -> `url.scheme`, `http.user_agent` ->
`user_agent.original`, `http.response_content_length` ->
`http.response.body.size`, `http.response_transfer_size` -> `http.response.size`,
and `url.same_origin` -> `http.request.same_origin`.

`http.request_content_length`, `http.request_content_length_uncompressed`,
`http.response_content_length_uncompressed` and `http.status_text` are left
alone — they are not in `@sentry/conventions` at all, so they have no
replacement to move to.

Three cases needed more than a rename:

- `http.target` carried pathname *and* query, while `url.path` is the pathname
  only. The core server span set neither `url.query` nor `url.fragment`, so
  dropping `http.target` would have lost the query — it now sets both, which
  the node server span already did.
- Consumers that matched on `http.target` were repointed at `url.path`: the
  react-router low-quality-transaction filter and the TanStack Start tunnel-route
  filter, both `ignoreSpans` rules against our own spans that would otherwise
  have silently stopped matching. The Next.js readers keep `http.target` as a
  fallback behind a `url.path` primary, since they also see spans from a user's
  own OpenTelemetry instrumentation. All other read-side fallbacks are untouched
  for the same reason.
- `http.host`, `http.flavor` and `http.client_ip` are dropped without a
  replacement being set here. Their replacements — `server.address`,
  `network.protocol.version` and `client.address` — are introduced by #23301, so
  setting them here too would mean two PRs writing the same keys with different
  values.

`SanitizedRequestData`, the shape backing `http` breadcrumb data, now keys the
method as `http.request.method`.

Span attributes in the touched files are now imported from
`@sentry/conventions/attributes` rather than written as string literals. That is
what surfaced `url.same_origin` as deprecated; as a literal it was invisible.

`no-unfiltered-url-attributes` no longer guards `http.target`: nothing sets it,
and its replacement `url.path` is a bare pathname with no query to filter.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@msonnb
msonnb force-pushed the ms/deprecated-http-net-attributes branch from 743aa06 to 477d4a1 Compare August 25, 2026 12:03
@msonnb msonnb changed the title ref(core)!: Replace deprecated http.* span attributes on HTTP spans feat!: Replace deprecated http.* span attributes on HTTP spans Aug 25, 2026
@msonnb

msonnb commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

will stack this

@msonnb msonnb closed this Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant