Skip to content

[Core] Fix KibanaRequest aborted$ never emitting for HTTP/2 requests - #285244

Merged
legrego merged 3 commits into
elastic:mainfrom
legrego:fix-aborted-http2-requests
Aug 17, 2026
Merged

legrego merged 3 commits into
elastic:mainfrom
legrego:fix-aborted-http2-requests

Conversation

@legrego

@legrego legrego commented Aug 14, 2026

Copy link
Copy Markdown
Member

Human summary

Improves the detection of completed requests by additionally checking for res.writableEnded. This works around a quirk in Node.js when running in http/2, which is resolved in 26+: nodejs/node#63249.

Checking for res.writableEnded does not change anything when running in http/1, as this is always true when res.writableFinished. This changes behavior for http/2 by properly detecting aborted requests.

This should result in downstream consumers having a more reliable signal for when a client request is aborted, allowing them to cancel jobs such as in-flight ES requests regardless of http protocol.

We detected this while writing scout tests for #285153

AI description

When an HTTP/2 client destroys a stream mid-request (RST_STREAM / NGHTTP2_CANCEL, e.g. an AbortController cancel or browser navigation), Node's Http2ServerResponse emits 'close' with writableFinished === true even though nothing was written. isCompleted() relied on writableFinished alone, so the !isCompleted filter swallowed the event and request.events.aborted$ never fired — consumers (route handlers, auth providers) could not observe HTTP/2 client aborts. HTTP/1 was unaffected because writableFinished stays false there.

Treat a request as completed only when writableFinished && writableEnded: writableEnded only becomes true once the server actually ended the response, and is truthful on both protocols and for abrupt TCP-level disconnects.

Adds integration coverage in http2_protocol.test.ts driving a real HTTP/2 TLS session that resets the stream while the handler is pending, plus a control test asserting completed$ (and not aborted$) on normal completion.

When an HTTP/2 client destroys a stream mid-request (RST_STREAM /
NGHTTP2_CANCEL, e.g. an AbortController cancel or browser navigation),
Node's Http2ServerResponse emits 'close' with writableFinished === true
even though nothing was written. isCompleted() relied on
writableFinished alone, so the !isCompleted filter swallowed the event
and request.events.aborted$ never fired — consumers (route handlers,
auth providers) could not observe HTTP/2 client aborts. HTTP/1 was
unaffected because writableFinished stays false there.

Treat a request as completed only when writableFinished &&
writableEnded: writableEnded only becomes true once the server actually
ended the response, and is truthful on both protocols and for abrupt
TCP-level disconnects.

Adds integration coverage in http2_protocol.test.ts driving a real
HTTP/2 TLS session that resets the stream while the handler is pending
(fails without the fix), plus a control test asserting completed$ (and
not aborted$) on normal completion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@legrego legrego added Team:Security Platform Security: Auth, Users, Roles, Spaces, Audit Logging, etc t// release_note:skip Skip the PR/issue when compiling release notes backport:all-open Backport to all branches that could still receive a release labels Aug 14, 2026
@legrego
legrego marked this pull request as ready for review August 14, 2026 17:52
@legrego
legrego requested a review from a team as a code owner August 14, 2026 17:52
@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

Pinging @elastic/kibana-security (Team:Security)

@legrego
legrego enabled auto-merge (squash) August 17, 2026 10:26
@kibanamachine

Copy link
Copy Markdown
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Metrics [docs]

✅ unchanged

Test Failures

  • [job] [logs] FTR Configs #89 / lens serverless - group 1 - subgroup 1 lens smokescreen tests should transition from a multi-layer stacked bar to a multi-layer line chart and correctly remove all layers
  • [job] [logs] Scout Lane #22 - stateful-classic / default / local-stateful-classic - StepDetailsPage - displays step detail metrics
  • [job] [logs] FTR Configs #122 / Serverless Common UI - Management Data View Management creating and deleting default data view index pattern deletion "before all" hook for "should return to index pattern list"
  • [job] [logs] Jest Tests #18 / useWorkflowExecutionPolling should handle status transitions during polling

History

@legrego
legrego merged commit a19e27a into elastic:main Aug 17, 2026
40 checks passed
@kibanamachine

Copy link
Copy Markdown
Contributor

Starting backport for target branches: 8.19, 9.4, 9.5

https://github.com/elastic/kibana/actions/runs/32027293038

@kibanamachine

Copy link
Copy Markdown
Contributor

💔 Some backports could not be created

Status Branch Result
8.19 Backport failed because of merge conflicts
9.4
9.5

Note: Successful backport PRs will be merged automatically after passing CI.

Manual backport

To create the backport manually run:

node scripts/backport --pr 285244

Questions ?

Please refer to the Backport tool documentation

kibanamachine added a commit that referenced this pull request Aug 17, 2026
…uests (#285244) (#285382)

# Backport

This will backport the following commits from `main` to `9.4`:
- [[Core] Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)](#285244)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Larry
Gregory","email":"larry.gregory@elastic.co"},"sourceCommit":{"committedDate":"2026-08-17T11:55:38Z","message":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)\n\n## Human summary\n\nImproves the detection of completed
requests by additionally checking\nfor `res.writableEnded`. This works
around a quirk in Node.js when\nrunning in http/2, which is resolved in
26+:\nhttps://github.com/nodejs/node/pull/63249.\n\nChecking for
`res.writableEnded` does not change anything when running\nin http/1, as
this is always true when `res.writableFinished`. This\nchanges behavior
for http/2 by properly detecting aborted requests.\n\nThis should result
in downstream consumers having a more reliable signal\nfor when a client
request is aborted, allowing them to cancel jobs such\nas in-flight ES
requests regardless of http protocol.\n\nWe detected this while writing
scout tests for\nhttps://github.com//pull/285153\n\n## AI
description\nWhen an HTTP/2 client destroys a stream mid-request
(RST_STREAM /\nNGHTTP2_CANCEL, e.g. an AbortController cancel or browser
navigation),\nNode's Http2ServerResponse emits 'close' with
writableFinished === true\neven though nothing was written.
isCompleted() relied on\nwritableFinished alone, so the !isCompleted
filter swallowed the event\nand request.events.aborted$ never fired —
consumers (route handlers,\nauth providers) could not observe HTTP/2
client aborts. HTTP/1 was\nunaffected because writableFinished stays
false there.\n\nTreat a request as completed only when writableFinished
&&\nwritableEnded: writableEnded only becomes true once the server
actually\nended the response, and is truthful on both protocols and for
abrupt\nTCP-level disconnects.\n\nAdds integration coverage in
http2_protocol.test.ts driving a real\nHTTP/2 TLS session that resets
the stream while the handler is pending,\nplus a control test asserting
completed$ (and not aborted$) on normal\ncompletion.\n\nCo-authored-by:
Claude Fable 5
<noreply@anthropic.com>","sha":"a19e27a5dc885a40a31998f728c450d8aee27289","branchLabelMapping":{"^v9.6.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Security","release_note:skip","backport:all-open","v9.6.0"],"title":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2
requests","number":285244,"url":"https://github.com/elastic/kibana/pull/285244","mergeCommit":{"message":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)\n\n## Human summary\n\nImproves the detection of completed
requests by additionally checking\nfor `res.writableEnded`. This works
around a quirk in Node.js when\nrunning in http/2, which is resolved in
26+:\nhttps://github.com/nodejs/node/pull/63249.\n\nChecking for
`res.writableEnded` does not change anything when running\nin http/1, as
this is always true when `res.writableFinished`. This\nchanges behavior
for http/2 by properly detecting aborted requests.\n\nThis should result
in downstream consumers having a more reliable signal\nfor when a client
request is aborted, allowing them to cancel jobs such\nas in-flight ES
requests regardless of http protocol.\n\nWe detected this while writing
scout tests for\nhttps://github.com//pull/285153\n\n## AI
description\nWhen an HTTP/2 client destroys a stream mid-request
(RST_STREAM /\nNGHTTP2_CANCEL, e.g. an AbortController cancel or browser
navigation),\nNode's Http2ServerResponse emits 'close' with
writableFinished === true\neven though nothing was written.
isCompleted() relied on\nwritableFinished alone, so the !isCompleted
filter swallowed the event\nand request.events.aborted$ never fired —
consumers (route handlers,\nauth providers) could not observe HTTP/2
client aborts. HTTP/1 was\nunaffected because writableFinished stays
false there.\n\nTreat a request as completed only when writableFinished
&&\nwritableEnded: writableEnded only becomes true once the server
actually\nended the response, and is truthful on both protocols and for
abrupt\nTCP-level disconnects.\n\nAdds integration coverage in
http2_protocol.test.ts driving a real\nHTTP/2 TLS session that resets
the stream while the handler is pending,\nplus a control test asserting
completed$ (and not aborted$) on normal\ncompletion.\n\nCo-authored-by:
Claude Fable 5
<noreply@anthropic.com>","sha":"a19e27a5dc885a40a31998f728c450d8aee27289"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.6.0","branchLabelMappingKey":"^v9.6.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/285244","number":285244,"mergeCommit":{"message":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)\n\n## Human summary\n\nImproves the detection of completed
requests by additionally checking\nfor `res.writableEnded`. This works
around a quirk in Node.js when\nrunning in http/2, which is resolved in
26+:\nhttps://github.com/nodejs/node/pull/63249.\n\nChecking for
`res.writableEnded` does not change anything when running\nin http/1, as
this is always true when `res.writableFinished`. This\nchanges behavior
for http/2 by properly detecting aborted requests.\n\nThis should result
in downstream consumers having a more reliable signal\nfor when a client
request is aborted, allowing them to cancel jobs such\nas in-flight ES
requests regardless of http protocol.\n\nWe detected this while writing
scout tests for\nhttps://github.com//pull/285153\n\n## AI
description\nWhen an HTTP/2 client destroys a stream mid-request
(RST_STREAM /\nNGHTTP2_CANCEL, e.g. an AbortController cancel or browser
navigation),\nNode's Http2ServerResponse emits 'close' with
writableFinished === true\neven though nothing was written.
isCompleted() relied on\nwritableFinished alone, so the !isCompleted
filter swallowed the event\nand request.events.aborted$ never fired —
consumers (route handlers,\nauth providers) could not observe HTTP/2
client aborts. HTTP/1 was\nunaffected because writableFinished stays
false there.\n\nTreat a request as completed only when writableFinished
&&\nwritableEnded: writableEnded only becomes true once the server
actually\nended the response, and is truthful on both protocols and for
abrupt\nTCP-level disconnects.\n\nAdds integration coverage in
http2_protocol.test.ts driving a real\nHTTP/2 TLS session that resets
the stream while the handler is pending,\nplus a control test asserting
completed$ (and not aborted$) on normal\ncompletion.\n\nCo-authored-by:
Claude Fable 5
<noreply@anthropic.com>","sha":"a19e27a5dc885a40a31998f728c450d8aee27289"}}]}]
BACKPORT-->

Co-authored-by: Larry Gregory <larry.gregory@elastic.co>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
kibanamachine added a commit that referenced this pull request Aug 17, 2026
…uests (#285244) (#285383)

# Backport

This will backport the following commits from `main` to `9.5`:
- [[Core] Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)](#285244)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Larry
Gregory","email":"larry.gregory@elastic.co"},"sourceCommit":{"committedDate":"2026-08-17T11:55:38Z","message":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)\n\n## Human summary\n\nImproves the detection of completed
requests by additionally checking\nfor `res.writableEnded`. This works
around a quirk in Node.js when\nrunning in http/2, which is resolved in
26+:\nhttps://github.com/nodejs/node/pull/63249.\n\nChecking for
`res.writableEnded` does not change anything when running\nin http/1, as
this is always true when `res.writableFinished`. This\nchanges behavior
for http/2 by properly detecting aborted requests.\n\nThis should result
in downstream consumers having a more reliable signal\nfor when a client
request is aborted, allowing them to cancel jobs such\nas in-flight ES
requests regardless of http protocol.\n\nWe detected this while writing
scout tests for\nhttps://github.com//pull/285153\n\n## AI
description\nWhen an HTTP/2 client destroys a stream mid-request
(RST_STREAM /\nNGHTTP2_CANCEL, e.g. an AbortController cancel or browser
navigation),\nNode's Http2ServerResponse emits 'close' with
writableFinished === true\neven though nothing was written.
isCompleted() relied on\nwritableFinished alone, so the !isCompleted
filter swallowed the event\nand request.events.aborted$ never fired —
consumers (route handlers,\nauth providers) could not observe HTTP/2
client aborts. HTTP/1 was\nunaffected because writableFinished stays
false there.\n\nTreat a request as completed only when writableFinished
&&\nwritableEnded: writableEnded only becomes true once the server
actually\nended the response, and is truthful on both protocols and for
abrupt\nTCP-level disconnects.\n\nAdds integration coverage in
http2_protocol.test.ts driving a real\nHTTP/2 TLS session that resets
the stream while the handler is pending,\nplus a control test asserting
completed$ (and not aborted$) on normal\ncompletion.\n\nCo-authored-by:
Claude Fable 5
<noreply@anthropic.com>","sha":"a19e27a5dc885a40a31998f728c450d8aee27289","branchLabelMapping":{"^v9.6.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Security","release_note:skip","backport:all-open","v9.6.0"],"title":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2
requests","number":285244,"url":"https://github.com/elastic/kibana/pull/285244","mergeCommit":{"message":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)\n\n## Human summary\n\nImproves the detection of completed
requests by additionally checking\nfor `res.writableEnded`. This works
around a quirk in Node.js when\nrunning in http/2, which is resolved in
26+:\nhttps://github.com/nodejs/node/pull/63249.\n\nChecking for
`res.writableEnded` does not change anything when running\nin http/1, as
this is always true when `res.writableFinished`. This\nchanges behavior
for http/2 by properly detecting aborted requests.\n\nThis should result
in downstream consumers having a more reliable signal\nfor when a client
request is aborted, allowing them to cancel jobs such\nas in-flight ES
requests regardless of http protocol.\n\nWe detected this while writing
scout tests for\nhttps://github.com//pull/285153\n\n## AI
description\nWhen an HTTP/2 client destroys a stream mid-request
(RST_STREAM /\nNGHTTP2_CANCEL, e.g. an AbortController cancel or browser
navigation),\nNode's Http2ServerResponse emits 'close' with
writableFinished === true\neven though nothing was written.
isCompleted() relied on\nwritableFinished alone, so the !isCompleted
filter swallowed the event\nand request.events.aborted$ never fired —
consumers (route handlers,\nauth providers) could not observe HTTP/2
client aborts. HTTP/1 was\nunaffected because writableFinished stays
false there.\n\nTreat a request as completed only when writableFinished
&&\nwritableEnded: writableEnded only becomes true once the server
actually\nended the response, and is truthful on both protocols and for
abrupt\nTCP-level disconnects.\n\nAdds integration coverage in
http2_protocol.test.ts driving a real\nHTTP/2 TLS session that resets
the stream while the handler is pending,\nplus a control test asserting
completed$ (and not aborted$) on normal\ncompletion.\n\nCo-authored-by:
Claude Fable 5
<noreply@anthropic.com>","sha":"a19e27a5dc885a40a31998f728c450d8aee27289"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.6.0","branchLabelMappingKey":"^v9.6.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/285244","number":285244,"mergeCommit":{"message":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)\n\n## Human summary\n\nImproves the detection of completed
requests by additionally checking\nfor `res.writableEnded`. This works
around a quirk in Node.js when\nrunning in http/2, which is resolved in
26+:\nhttps://github.com/nodejs/node/pull/63249.\n\nChecking for
`res.writableEnded` does not change anything when running\nin http/1, as
this is always true when `res.writableFinished`. This\nchanges behavior
for http/2 by properly detecting aborted requests.\n\nThis should result
in downstream consumers having a more reliable signal\nfor when a client
request is aborted, allowing them to cancel jobs such\nas in-flight ES
requests regardless of http protocol.\n\nWe detected this while writing
scout tests for\nhttps://github.com//pull/285153\n\n## AI
description\nWhen an HTTP/2 client destroys a stream mid-request
(RST_STREAM /\nNGHTTP2_CANCEL, e.g. an AbortController cancel or browser
navigation),\nNode's Http2ServerResponse emits 'close' with
writableFinished === true\neven though nothing was written.
isCompleted() relied on\nwritableFinished alone, so the !isCompleted
filter swallowed the event\nand request.events.aborted$ never fired —
consumers (route handlers,\nauth providers) could not observe HTTP/2
client aborts. HTTP/1 was\nunaffected because writableFinished stays
false there.\n\nTreat a request as completed only when writableFinished
&&\nwritableEnded: writableEnded only becomes true once the server
actually\nended the response, and is truthful on both protocols and for
abrupt\nTCP-level disconnects.\n\nAdds integration coverage in
http2_protocol.test.ts driving a real\nHTTP/2 TLS session that resets
the stream while the handler is pending,\nplus a control test asserting
completed$ (and not aborted$) on normal\ncompletion.\n\nCo-authored-by:
Claude Fable 5
<noreply@anthropic.com>","sha":"a19e27a5dc885a40a31998f728c450d8aee27289"}}]}]
BACKPORT-->

Co-authored-by: Larry Gregory <larry.gregory@elastic.co>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@legrego

legrego commented Aug 17, 2026

Copy link
Copy Markdown
Member Author

💚 All backports created successfully

Status Branch Result
8.19

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

jr-araque pushed a commit to jr-araque/kibana that referenced this pull request Aug 18, 2026
…lastic#285244)

## Human summary

Improves the detection of completed requests by additionally checking
for `res.writableEnded`. This works around a quirk in Node.js when
running in http/2, which is resolved in 26+:
nodejs/node#63249.

Checking for `res.writableEnded` does not change anything when running
in http/1, as this is always true when `res.writableFinished`. This
changes behavior for http/2 by properly detecting aborted requests.

This should result in downstream consumers having a more reliable signal
for when a client request is aborted, allowing them to cancel jobs such
as in-flight ES requests regardless of http protocol.

We detected this while writing scout tests for
elastic#285153

## AI description
When an HTTP/2 client destroys a stream mid-request (RST_STREAM /
NGHTTP2_CANCEL, e.g. an AbortController cancel or browser navigation),
Node's Http2ServerResponse emits 'close' with writableFinished === true
even though nothing was written. isCompleted() relied on
writableFinished alone, so the !isCompleted filter swallowed the event
and request.events.aborted$ never fired — consumers (route handlers,
auth providers) could not observe HTTP/2 client aborts. HTTP/1 was
unaffected because writableFinished stays false there.

Treat a request as completed only when writableFinished &&
writableEnded: writableEnded only becomes true once the server actually
ended the response, and is truthful on both protocols and for abrupt
TCP-level disconnects.

Adds integration coverage in http2_protocol.test.ts driving a real
HTTP/2 TLS session that resets the stream while the handler is pending,
plus a control test asserting completed$ (and not aborted$) on normal
completion.
@kibanamachine kibanamachine added the backport missing Added to PRs automatically when the are determined to be missing a backport. label Aug 19, 2026
@kibanamachine

Copy link
Copy Markdown
Contributor

Looks like this PR has backport PRs but they still haven't been merged. Please merge them ASAP to keep the branches relatively in sync.
cc: @legrego

legrego added a commit that referenced this pull request Aug 19, 2026
…quests (#285244) (#285403)

# Backport

This will backport the following commits from `main` to `8.19`:
- [[Core] Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)](#285244)

<!--- Backport version: 11.0.2 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Larry
Gregory","email":"larry.gregory@elastic.co"},"sourceCommit":{"committedDate":"2026-08-17T11:55:38Z","message":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)\n\n## Human summary\n\nImproves the detection of completed
requests by additionally checking\nfor `res.writableEnded`. This works
around a quirk in Node.js when\nrunning in http/2, which is resolved in
26+:\nhttps://github.com/nodejs/node/pull/63249.\n\nChecking for
`res.writableEnded` does not change anything when running\nin http/1, as
this is always true when `res.writableFinished`. This\nchanges behavior
for http/2 by properly detecting aborted requests.\n\nThis should result
in downstream consumers having a more reliable signal\nfor when a client
request is aborted, allowing them to cancel jobs such\nas in-flight ES
requests regardless of http protocol.\n\nWe detected this while writing
scout tests for\nhttps://github.com//pull/285153\n\n## AI
description\nWhen an HTTP/2 client destroys a stream mid-request
(RST_STREAM /\nNGHTTP2_CANCEL, e.g. an AbortController cancel or browser
navigation),\nNode's Http2ServerResponse emits 'close' with
writableFinished === true\neven though nothing was written.
isCompleted() relied on\nwritableFinished alone, so the !isCompleted
filter swallowed the event\nand request.events.aborted$ never fired —
consumers (route handlers,\nauth providers) could not observe HTTP/2
client aborts. HTTP/1 was\nunaffected because writableFinished stays
false there.\n\nTreat a request as completed only when writableFinished
&&\nwritableEnded: writableEnded only becomes true once the server
actually\nended the response, and is truthful on both protocols and for
abrupt\nTCP-level disconnects.\n\nAdds integration coverage in
http2_protocol.test.ts driving a real\nHTTP/2 TLS session that resets
the stream while the handler is pending,\nplus a control test asserting
completed$ (and not aborted$) on normal\ncompletion.\n\nCo-authored-by:
Claude Fable 5
<noreply@anthropic.com>","sha":"a19e27a5dc885a40a31998f728c450d8aee27289","branchLabelMapping":{"^v9.6.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Security","release_note:skip","backport:all-open","v9.6.0","v9.4.6","v9.5.2"],"title":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2
requests","number":285244,"url":"https://github.com/elastic/kibana/pull/285244","mergeCommit":{"message":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)\n\n## Human summary\n\nImproves the detection of completed
requests by additionally checking\nfor `res.writableEnded`. This works
around a quirk in Node.js when\nrunning in http/2, which is resolved in
26+:\nhttps://github.com/nodejs/node/pull/63249.\n\nChecking for
`res.writableEnded` does not change anything when running\nin http/1, as
this is always true when `res.writableFinished`. This\nchanges behavior
for http/2 by properly detecting aborted requests.\n\nThis should result
in downstream consumers having a more reliable signal\nfor when a client
request is aborted, allowing them to cancel jobs such\nas in-flight ES
requests regardless of http protocol.\n\nWe detected this while writing
scout tests for\nhttps://github.com//pull/285153\n\n## AI
description\nWhen an HTTP/2 client destroys a stream mid-request
(RST_STREAM /\nNGHTTP2_CANCEL, e.g. an AbortController cancel or browser
navigation),\nNode's Http2ServerResponse emits 'close' with
writableFinished === true\neven though nothing was written.
isCompleted() relied on\nwritableFinished alone, so the !isCompleted
filter swallowed the event\nand request.events.aborted$ never fired —
consumers (route handlers,\nauth providers) could not observe HTTP/2
client aborts. HTTP/1 was\nunaffected because writableFinished stays
false there.\n\nTreat a request as completed only when writableFinished
&&\nwritableEnded: writableEnded only becomes true once the server
actually\nended the response, and is truthful on both protocols and for
abrupt\nTCP-level disconnects.\n\nAdds integration coverage in
http2_protocol.test.ts driving a real\nHTTP/2 TLS session that resets
the stream while the handler is pending,\nplus a control test asserting
completed$ (and not aborted$) on normal\ncompletion.\n\nCo-authored-by:
Claude Fable 5
<noreply@anthropic.com>","sha":"a19e27a5dc885a40a31998f728c450d8aee27289"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.6.0","branchLabelMappingKey":"^v9.6.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/285244","number":285244,"mergeCommit":{"message":"[Core]
Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244)\n\n## Human summary\n\nImproves the detection of completed
requests by additionally checking\nfor `res.writableEnded`. This works
around a quirk in Node.js when\nrunning in http/2, which is resolved in
26+:\nhttps://github.com/nodejs/node/pull/63249.\n\nChecking for
`res.writableEnded` does not change anything when running\nin http/1, as
this is always true when `res.writableFinished`. This\nchanges behavior
for http/2 by properly detecting aborted requests.\n\nThis should result
in downstream consumers having a more reliable signal\nfor when a client
request is aborted, allowing them to cancel jobs such\nas in-flight ES
requests regardless of http protocol.\n\nWe detected this while writing
scout tests for\nhttps://github.com//pull/285153\n\n## AI
description\nWhen an HTTP/2 client destroys a stream mid-request
(RST_STREAM /\nNGHTTP2_CANCEL, e.g. an AbortController cancel or browser
navigation),\nNode's Http2ServerResponse emits 'close' with
writableFinished === true\neven though nothing was written.
isCompleted() relied on\nwritableFinished alone, so the !isCompleted
filter swallowed the event\nand request.events.aborted$ never fired —
consumers (route handlers,\nauth providers) could not observe HTTP/2
client aborts. HTTP/1 was\nunaffected because writableFinished stays
false there.\n\nTreat a request as completed only when writableFinished
&&\nwritableEnded: writableEnded only becomes true once the server
actually\nended the response, and is truthful on both protocols and for
abrupt\nTCP-level disconnects.\n\nAdds integration coverage in
http2_protocol.test.ts driving a real\nHTTP/2 TLS session that resets
the stream while the handler is pending,\nplus a control test asserting
completed$ (and not aborted$) on normal\ncompletion.\n\nCo-authored-by:
Claude Fable 5
<noreply@anthropic.com>","sha":"a19e27a5dc885a40a31998f728c450d8aee27289"}},{"branch":"9.4","label":"v9.4.6","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/285382","number":285382,"state":"MERGED","mergeCommit":{"sha":"8cb7c7f6e2b21af321412223579d0eab0f0b8134","message":"[9.4]
[Core] Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244) (#285382)\n\n# Backport\n\nThis will backport the following
commits from `main` to `9.4`:\n- [[Core] Fix KibanaRequest aborted$
never emitting for HTTP/2
requests\n(#285244)](https://github.com/elastic/kibana/pull/285244)\n\n\n\n###
Questions ?\nPlease refer to the [Backport
tool\ndocumentation](https://github.com/sorenlouv/backport)\n\n\n\nCo-authored-by:
Larry Gregory <larry.gregory@elastic.co>\nCo-authored-by: Claude Fable 5
<noreply@anthropic.com>"}},{"branch":"9.5","label":"v9.5.2","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/285383","number":285383,"state":"MERGED","mergeCommit":{"sha":"aeff16c0cbf64223297cf496f698e03a793c24bf","message":"[9.5]
[Core] Fix KibanaRequest aborted$ never emitting for HTTP/2 requests
(#285244) (#285383)\n\n# Backport\n\nThis will backport the following
commits from `main` to `9.5`:\n- [[Core] Fix KibanaRequest aborted$
never emitting for HTTP/2
requests\n(#285244)](https://github.com/elastic/kibana/pull/285244)\n\n\n\n###
Questions ?\nPlease refer to the [Backport
tool\ndocumentation](https://github.com/sorenlouv/backport)\n\n\n\nCo-authored-by:
Larry Gregory <larry.gregory@elastic.co>\nCo-authored-by: Claude Fable 5
<noreply@anthropic.com>"}}]}] BACKPORT-->
@kibanamachine kibanamachine added v8.19.21 and removed backport missing Added to PRs automatically when the are determined to be missing a backport. labels Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:all-open Backport to all branches that could still receive a release release_note:skip Skip the PR/issue when compiling release notes Team:Security Platform Security: Auth, Users, Roles, Spaces, Audit Logging, etc t// v8.19.21 v9.4.6 v9.5.2 v9.6.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants