Skip to content

macOS Big Sur x64: Large HTTP bodies result in broken responses #38709

@borgstrom

Description

@borgstrom
  • Version: v16.1.0 (also tried with v14.17.0, and v10.24.1)
  • Platform: Darwin sdamianotest 20.4.0 Darwin Kernel Version 20.4.0: Thu Apr 22 21:46:47 PDT 2021; root:xnu-7195.101.2~1/RELEASE_X86_64 x86_64
  • macOS: 11.3.1 (20E241)
  • Subsystem:

We have x64 macbooks with Big Sur on them and our team mates have run into a very strange bug that we are hoping to get some assistance debugging.

This only affects x64 (Intel) machines running Big Sur. The arm (M1) machines running Big Sur are not affected.

The most succinct way to describe the problem is:

Node.js HTTP applications running on Intel Mac's with Big Sur fail to respond correctly when the body size exceeds a certain size for requests that arrive on any address except 127.0.0.1.

The response is missing the first part and just begins in the middle of the payload.

This is problematic for us because our local development process routes traffic to interface addresses rather than the loopback address, so when we try to forward traffic to the node process via nginx we get the following in the logs:

2021/05/12 17:18:30 [error] 16#0: *139 upstream sent no valid HTTP/1.0 header while reading response header from upstream

What steps will reproduce the bug?

We can easily reproduce the bug with two simple js files using express or koa:

app1.js

const express = require('express');
const app = express();
app.get('/', (req, res) => {
  const str = new Array(10000)
    .fill(0)
    .map((n, i) => String(i).padStart(10, '0'))
    .join('.');
  res.send(str);
});
app.listen(12345, () => console.log('listening!'));

app2.js

const Koa = require('koa');
const app = module.exports = new Koa();

app.use(async function(ctx) {
  ctx.body = new Array(10000)
    .fill(0)
    .map((n, i) => String(i).padStart(10, '0'))
    .join('.');
});

if (!module.parent) app.listen(12345)

Get the address of your primary network interface (i.e. ifconfig en0 for me yields 10.0.0.99)

Run either of the js files:

node app1.js

Attempt to communicate with the server over the IP address of your network interface:

curl -v http://10.0.0.99:12345/ |& less

You will that the response does not contain the response headers and starts in the middle of the response:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
^M  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 10.0.0.99...
* TCP_NODELAY set
* Connected to 10.0.0.99 (10.0.0.99) port 12345 (#0)
> GET / HTTP/1.1
> Host: 10.0.0.99:12345
> User-Agent: curl/7.64.1
> Accept: */*
> 
{ [44675 bytes data]
5938.0000005939.0000005940.<snip...>

If you use the loopback:

curl -v http://127.0.0.1:12345/ |& less

Then you get the expected response:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
^M  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 10.0.0.99...
* TCP_NODELAY set
* Connected to 10.0.0.99 (10.0.0.99) port 12345 (#0)
> GET / HTTP/1.1
> Host: 10.0.0.99:12345
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 109999
< ETag: W/"1adaf-NIJ59faoC2M+qf00tsCBtYMIueY"
< Date: Mon, 17 May 2021 17:53:22 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< 
{ [97757 bytes data]
0000000000.0000000001.0000000002. <snip...>

Metadata

Metadata

Assignees

No one assigned

    Labels

    httpIssues or PRs related to the http subsystem.macosIssues and PRs related to the macOS platform / OSX.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions