koa: http2 throws ERR_HTTP2_INVALID_STREAM with minor amount of concurrency
Moving from https://github.com/nodejs/node/issues/22135; as per the comments, it was confirmed to be koa-specific.
- Version:
v10.8.0 - Platform:
Linux 86f664ae731c 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:55:56 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux(ubuntu:18.04Docker image) - Subsystem:
http2
After a small handful of concurrent requests, http2 fails with the following error:
internal/http2/core.js:1791
throw new ERR_HTTP2_INVALID_STREAM();
^
Error [ERR_HTTP2_INVALID_STREAM]: The stream has been destroyed
at ServerHttp2Stream.sendTrailers (internal/http2/core.js:1791:13)
at ServerHttp2Stream.onStreamTrailersReady (internal/http2/compat.js:377:8)
at ServerHttp2Stream.emit (events.js:182:13)
at Http2Stream.onStreamTrailers [as ontrailers] (internal/http2/core.js:318:15)
at ServerHttp2Stream.submitRstStream (internal/http2/core.js:328:19)
at ServerHttp2Stream.finishCloseStream (internal/http2/core.js:1533:3)
at closeStream (internal/http2/core.js:1517:7)
at ServerHttp2Stream.close (internal/http2/core.js:1846:5)
at state.streams.forEach (internal/http2/core.js:2691:46)
at Map.forEach (<anonymous>)
Test case:
cat > server.js << EOM
const app = new (require('koa'))();
const crypto = require('crypto');
const fs = require('fs');
const http2 = require('http2');
app.use(async ctx => {
await new Promise(resolve => setTimeout(resolve, 1000));
ctx.body = 'balls';
ctx.status = 200;
});
http2.createSecureServer(
{
allowHTTP1: true,
cert: fs.readFileSync('cert.pem'),
key: fs.readFileSync('key.pem'),
dhparam: fs.readFileSync('dhparams.pem'),
secureOptions:
crypto.constants.SSL_OP_NO_SSLv3 |
crypto.constants.SSL_OP_NO_TLSv1
},
app.callback()
).listen(
31337
);
EOM
killall node
node server.js &
echo -n > count
while ps ux | grep server.js | grep -v grep 2> /dev/null ; do
echo -e '1\n2\n3\n4\n5\n6\n7\n8\n9\n10'
done | xargs -P10 bash -c '
echo >> count
curl -sk https://localhost:31337 > /dev/null
'
When the error occurs, you can manually kill the command with ctrl+C and wc -l count to view how many requests were initiated before the failure. For me it’s been anywhere between 10 and 70.
This doesn’t seem to be reproducible when using either https or spdy instead of http2.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 20 (11 by maintainers)
I’ve fixed the issue in Node, and the PR has been merged. https://github.com/nodejs/node/pull/23146
If anyone wants to try they can build the latest
masteror wait for the next release.It seems to be Koa-specific based on the issue linked at the top.
@buu700 did you manage to solve this issue?
Here a small repro:
The plain http2 server works fine, but the koa+http2 server kills the process because of a SIGINT: it’s like koa is trying to send content over a closed stream because the process dies after koa processed the request (the “curl” actually receives data but in the meanwhile node dies!).
Yea, I noticed you had Docker listed. I don’t have it installed and about to head to sleep for the night. If no one else stops by I’ll take another stab with Docker.