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

feat!: Replace deprecated http.* span attributes on HTTP spans#23423
msonnb wants to merge 1 commit into
developfrom
ms/deprecated-http-net-attributes

Conversation

@msonnb

@msonnbmsonnb 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

Copy link
Copy Markdown
MemberAuthor

bugbot run

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.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 flags77.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/react30.33 kB--
@sentry/react (incl. Tracing)50.7 kB-0.02%-7 B 🔽
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.72 kB-0.04%-18 B 🔽
@sentry/svelte28.6 kB--
CDN Bundle30.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 - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.59 kB-0.04%-55 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.28 kB-0.04%-55 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.18 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.87 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.54 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.56 kB-0.02%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.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/server64.97 kB-0.22%-140 B 🔽
@sentry/core/browser52.29 kB+0.05%+26 B 🔺
@sentry/node121.39 kB-0.3%-357 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.45 kB-0.12%-103 B 🔽
@sentry/aws-serverless95.59 kB-0.4%-377 B 🔽
@sentry/cloudflare (withSentry) - minified196.91 kB+0.01%+13 B 🔺
@sentry/cloudflare (withSentry)487.49 kB+0.01%+20 B 🔺

View base workflow run

@cursorcursorBot 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 CursorFix 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 CursorFix 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 CursorFix 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 CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

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

@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 71a94a4 to afc9274CompareAugust 24, 2026 08:35
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* and net.* span attributes on HTTPS spansref(core)!: Replace deprecated http.* span attributes on HTTP spansAug 24, 2026
@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch 3 times, most recently from 5177d40 to 743aa06CompareAugust 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
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 743aa06 to 477d4a1CompareAugust 25, 2026 12:03
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* span attributes on HTTP spansfeat!: Replace deprecated http.* span attributes on HTTP spansAug 25, 2026
@msonnb

Copy link
Copy Markdown
MemberAuthor

will stack this

@msonnbmsonnb closed this Aug 25, 2026
Sign up for freeto 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

@msonnb
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
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

feat!: Replace deprecated http.* span attributes on HTTP spans#23423
msonnb wants to merge 1 commit into
developfrom
ms/deprecated-http-net-attributes

Conversation

@msonnb

@msonnbmsonnb 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

Copy link
Copy Markdown
MemberAuthor

bugbot run

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.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 flags77.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/react30.33 kB--
@sentry/react (incl. Tracing)50.7 kB-0.02%-7 B 🔽
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.72 kB-0.04%-18 B 🔽
@sentry/svelte28.6 kB--
CDN Bundle30.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 - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.59 kB-0.04%-55 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.28 kB-0.04%-55 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.18 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.87 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.54 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.56 kB-0.02%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.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/server64.97 kB-0.22%-140 B 🔽
@sentry/core/browser52.29 kB+0.05%+26 B 🔺
@sentry/node121.39 kB-0.3%-357 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.45 kB-0.12%-103 B 🔽
@sentry/aws-serverless95.59 kB-0.4%-377 B 🔽
@sentry/cloudflare (withSentry) - minified196.91 kB+0.01%+13 B 🔺
@sentry/cloudflare (withSentry)487.49 kB+0.01%+20 B 🔺

View base workflow run

@cursorcursorBot 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 CursorFix 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 CursorFix 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 CursorFix 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 CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

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

@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 71a94a4 to afc9274CompareAugust 24, 2026 08:35
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* and net.* span attributes on HTTPS spansref(core)!: Replace deprecated http.* span attributes on HTTP spansAug 24, 2026
@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch 3 times, most recently from 5177d40 to 743aa06CompareAugust 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
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 743aa06 to 477d4a1CompareAugust 25, 2026 12:03
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* span attributes on HTTP spansfeat!: Replace deprecated http.* span attributes on HTTP spansAug 25, 2026
@msonnb

Copy link
Copy Markdown
MemberAuthor

will stack this

@msonnbmsonnb closed this Aug 25, 2026
Sign up for freeto 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

@msonnb
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

feat!: Replace deprecated http.* span attributes on HTTP spans#23423
msonnb wants to merge 1 commit into
developfrom
ms/deprecated-http-net-attributes

Conversation

@msonnb

@msonnbmsonnb 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

Copy link
Copy Markdown
MemberAuthor

bugbot run

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.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 flags77.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/react30.33 kB--
@sentry/react (incl. Tracing)50.7 kB-0.02%-7 B 🔽
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.72 kB-0.04%-18 B 🔽
@sentry/svelte28.6 kB--
CDN Bundle30.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 - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.59 kB-0.04%-55 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.28 kB-0.04%-55 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.18 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.87 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.54 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.56 kB-0.02%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.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/server64.97 kB-0.22%-140 B 🔽
@sentry/core/browser52.29 kB+0.05%+26 B 🔺
@sentry/node121.39 kB-0.3%-357 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.45 kB-0.12%-103 B 🔽
@sentry/aws-serverless95.59 kB-0.4%-377 B 🔽
@sentry/cloudflare (withSentry) - minified196.91 kB+0.01%+13 B 🔺
@sentry/cloudflare (withSentry)487.49 kB+0.01%+20 B 🔺

View base workflow run

@cursorcursorBot 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 CursorFix 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 CursorFix 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 CursorFix 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 CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

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

@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 71a94a4 to afc9274CompareAugust 24, 2026 08:35
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* and net.* span attributes on HTTPS spansref(core)!: Replace deprecated http.* span attributes on HTTP spansAug 24, 2026
@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch 3 times, most recently from 5177d40 to 743aa06CompareAugust 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
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 743aa06 to 477d4a1CompareAugust 25, 2026 12:03
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* span attributes on HTTP spansfeat!: Replace deprecated http.* span attributes on HTTP spansAug 25, 2026
@msonnb

Copy link
Copy Markdown
MemberAuthor

will stack this

@msonnbmsonnb closed this Aug 25, 2026
Sign up for freeto 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

@msonnb
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

feat!: Replace deprecated http.* span attributes on HTTP spans#23423
msonnb wants to merge 1 commit into
developfrom
ms/deprecated-http-net-attributes

Conversation

@msonnb

@msonnbmsonnb 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

Copy link
Copy Markdown
MemberAuthor

bugbot run

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.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 flags77.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/react30.33 kB--
@sentry/react (incl. Tracing)50.7 kB-0.02%-7 B 🔽
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.72 kB-0.04%-18 B 🔽
@sentry/svelte28.6 kB--
CDN Bundle30.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 - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.59 kB-0.04%-55 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.28 kB-0.04%-55 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.18 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.87 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.54 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.56 kB-0.02%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.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/server64.97 kB-0.22%-140 B 🔽
@sentry/core/browser52.29 kB+0.05%+26 B 🔺
@sentry/node121.39 kB-0.3%-357 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.45 kB-0.12%-103 B 🔽
@sentry/aws-serverless95.59 kB-0.4%-377 B 🔽
@sentry/cloudflare (withSentry) - minified196.91 kB+0.01%+13 B 🔺
@sentry/cloudflare (withSentry)487.49 kB+0.01%+20 B 🔺

View base workflow run

@cursorcursorBot 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 CursorFix 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 CursorFix 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 CursorFix 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 CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

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

@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 71a94a4 to afc9274CompareAugust 24, 2026 08:35
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* and net.* span attributes on HTTPS spansref(core)!: Replace deprecated http.* span attributes on HTTP spansAug 24, 2026
@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch 3 times, most recently from 5177d40 to 743aa06CompareAugust 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
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 743aa06 to 477d4a1CompareAugust 25, 2026 12:03
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* span attributes on HTTP spansfeat!: Replace deprecated http.* span attributes on HTTP spansAug 25, 2026
@msonnb

Copy link
Copy Markdown
MemberAuthor

will stack this

@msonnbmsonnb closed this Aug 25, 2026
Sign up for freeto 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

@msonnb
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
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

feat!: Replace deprecated http.* span attributes on HTTP spans#23423
msonnb wants to merge 1 commit into
developfrom
ms/deprecated-http-net-attributes

Conversation

@msonnb

@msonnbmsonnb 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

Copy link
Copy Markdown
MemberAuthor

bugbot run

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.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 flags77.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/react30.33 kB--
@sentry/react (incl. Tracing)50.7 kB-0.02%-7 B 🔽
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.72 kB-0.04%-18 B 🔽
@sentry/svelte28.6 kB--
CDN Bundle30.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 - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.59 kB-0.04%-55 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.28 kB-0.04%-55 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.18 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.87 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.54 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.56 kB-0.02%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.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/server64.97 kB-0.22%-140 B 🔽
@sentry/core/browser52.29 kB+0.05%+26 B 🔺
@sentry/node121.39 kB-0.3%-357 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.45 kB-0.12%-103 B 🔽
@sentry/aws-serverless95.59 kB-0.4%-377 B 🔽
@sentry/cloudflare (withSentry) - minified196.91 kB+0.01%+13 B 🔺
@sentry/cloudflare (withSentry)487.49 kB+0.01%+20 B 🔺

View base workflow run

@cursorcursorBot 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 CursorFix 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 CursorFix 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 CursorFix 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 CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

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

@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 71a94a4 to afc9274CompareAugust 24, 2026 08:35
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* and net.* span attributes on HTTPS spansref(core)!: Replace deprecated http.* span attributes on HTTP spansAug 24, 2026
@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch 3 times, most recently from 5177d40 to 743aa06CompareAugust 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
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 743aa06 to 477d4a1CompareAugust 25, 2026 12:03
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* span attributes on HTTP spansfeat!: Replace deprecated http.* span attributes on HTTP spansAug 25, 2026
@msonnb

Copy link
Copy Markdown
MemberAuthor

will stack this

@msonnbmsonnb closed this Aug 25, 2026
Sign up for freeto 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

@msonnb
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

feat!: Replace deprecated http.* span attributes on HTTP spans#23423
msonnb wants to merge 1 commit into
developfrom
ms/deprecated-http-net-attributes

Conversation

@msonnb

@msonnbmsonnb 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

Copy link
Copy Markdown
MemberAuthor

bugbot run

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.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 flags77.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/react30.33 kB--
@sentry/react (incl. Tracing)50.7 kB-0.02%-7 B 🔽
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.72 kB-0.04%-18 B 🔽
@sentry/svelte28.6 kB--
CDN Bundle30.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 - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.59 kB-0.04%-55 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.28 kB-0.04%-55 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.18 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.87 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.54 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.56 kB-0.02%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.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/server64.97 kB-0.22%-140 B 🔽
@sentry/core/browser52.29 kB+0.05%+26 B 🔺
@sentry/node121.39 kB-0.3%-357 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.45 kB-0.12%-103 B 🔽
@sentry/aws-serverless95.59 kB-0.4%-377 B 🔽
@sentry/cloudflare (withSentry) - minified196.91 kB+0.01%+13 B 🔺
@sentry/cloudflare (withSentry)487.49 kB+0.01%+20 B 🔺

View base workflow run

@cursorcursorBot 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 CursorFix 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 CursorFix 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 CursorFix 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 CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

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

@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 71a94a4 to afc9274CompareAugust 24, 2026 08:35
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* and net.* span attributes on HTTPS spansref(core)!: Replace deprecated http.* span attributes on HTTP spansAug 24, 2026
@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch 3 times, most recently from 5177d40 to 743aa06CompareAugust 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
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 743aa06 to 477d4a1CompareAugust 25, 2026 12:03
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* span attributes on HTTP spansfeat!: Replace deprecated http.* span attributes on HTTP spansAug 25, 2026
@msonnb

Copy link
Copy Markdown
MemberAuthor

will stack this

@msonnbmsonnb closed this Aug 25, 2026
Sign up for freeto 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

@msonnb
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

feat!: Replace deprecated http.* span attributes on HTTP spans#23423
msonnb wants to merge 1 commit into
developfrom
ms/deprecated-http-net-attributes

Conversation

@msonnb

@msonnbmsonnb 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

Copy link
Copy Markdown
MemberAuthor

bugbot run

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.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 flags77.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/react30.33 kB--
@sentry/react (incl. Tracing)50.7 kB-0.02%-7 B 🔽
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.72 kB-0.04%-18 B 🔽
@sentry/svelte28.6 kB--
CDN Bundle30.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 - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.59 kB-0.04%-55 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.28 kB-0.04%-55 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.18 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.87 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.54 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.56 kB-0.02%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.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/server64.97 kB-0.22%-140 B 🔽
@sentry/core/browser52.29 kB+0.05%+26 B 🔺
@sentry/node121.39 kB-0.3%-357 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.45 kB-0.12%-103 B 🔽
@sentry/aws-serverless95.59 kB-0.4%-377 B 🔽
@sentry/cloudflare (withSentry) - minified196.91 kB+0.01%+13 B 🔺
@sentry/cloudflare (withSentry)487.49 kB+0.01%+20 B 🔺

View base workflow run

@cursorcursorBot 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 CursorFix 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 CursorFix 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 CursorFix 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 CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

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

@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 71a94a4 to afc9274CompareAugust 24, 2026 08:35
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* and net.* span attributes on HTTPS spansref(core)!: Replace deprecated http.* span attributes on HTTP spansAug 24, 2026
@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch 3 times, most recently from 5177d40 to 743aa06CompareAugust 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
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 743aa06 to 477d4a1CompareAugust 25, 2026 12:03
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* span attributes on HTTP spansfeat!: Replace deprecated http.* span attributes on HTTP spansAug 25, 2026
@msonnb

Copy link
Copy Markdown
MemberAuthor

will stack this

@msonnbmsonnb closed this Aug 25, 2026
Sign up for freeto 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

@msonnb
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
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

feat!: Replace deprecated http.* span attributes on HTTP spans#23423
msonnb wants to merge 1 commit into
developfrom
ms/deprecated-http-net-attributes

Conversation

@msonnb

@msonnbmsonnb 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

Copy link
Copy Markdown
MemberAuthor

bugbot run

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.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 flags77.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/react30.33 kB--
@sentry/react (incl. Tracing)50.7 kB-0.02%-7 B 🔽
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.72 kB-0.04%-18 B 🔽
@sentry/svelte28.6 kB--
CDN Bundle30.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 - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.59 kB-0.04%-55 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.28 kB-0.04%-55 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.18 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.87 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.54 kB-0.03%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.56 kB-0.02%-55 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.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/server64.97 kB-0.22%-140 B 🔽
@sentry/core/browser52.29 kB+0.05%+26 B 🔺
@sentry/node121.39 kB-0.3%-357 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.45 kB-0.12%-103 B 🔽
@sentry/aws-serverless95.59 kB-0.4%-377 B 🔽
@sentry/cloudflare (withSentry) - minified196.91 kB+0.01%+13 B 🔺
@sentry/cloudflare (withSentry)487.49 kB+0.01%+20 B 🔺

View base workflow run

@cursorcursorBot 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 CursorFix 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 CursorFix 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 CursorFix 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 CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

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

@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 71a94a4 to afc9274CompareAugust 24, 2026 08:35
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* and net.* span attributes on HTTPS spansref(core)!: Replace deprecated http.* span attributes on HTTP spansAug 24, 2026
@msonnb
msonnbforce-pushed the ms/deprecated-http-net-attributes branch 3 times, most recently from 5177d40 to 743aa06CompareAugust 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
msonnbforce-pushed the ms/deprecated-http-net-attributes branch from 743aa06 to 477d4a1CompareAugust 25, 2026 12:03
@msonnbmsonnb changed the title ref(core)!: Replace deprecated http.* span attributes on HTTP spansfeat!: Replace deprecated http.* span attributes on HTTP spansAug 25, 2026
@msonnb

Copy link
Copy Markdown
MemberAuthor

will stack this

@msonnbmsonnb closed this Aug 25, 2026
Sign up for freeto 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

@msonnb