Skip to content

rawHeaders can exceed maxHeadersCount limit due to batch flush logic #61284

@Meltedd

Description

@Meltedd

Version

v25.2.1

Platform

Linux okcomputer 6.18.1-arch1-2.1-g14 #1 SMP PREEMPT_DYNAMIC Sat, 20 Dec 2025 08:57:00 +0000 x86_64 GNU/Linux

Subsystem

http

What steps will reproduce the bug?

const http = require('http');
const net = require('net');

const server = http.createServer((req, res) => {
  const limit = server.maxHeadersCount * 2;
  console.log(`rawHeaders.length=${req.rawHeaders.length}, limit=${limit}`);
  res.end();
  server.close();
});

server.maxHeadersCount = 50;

server.listen(0, () => {
  const port = server.address().port;
  const headers = Array.from({ length: 65 }, (_, i) => `X-${i}:v`).join('\r\n');
  const req = `GET / HTTP/1.1\r\nHost: localhost\r\n${headers}\r\n\r\n`;
  
  net.createConnection(port, 'localhost', function() {
    this.write(req);
    this.once('data', () => this.end());
  });
});

How often does it reproduce? Is there a required condition?

Always. Required condition is to send more than 32 headers to trigger the native parser's batch flush.

What is the expected behavior? Why is that the expected behavior?

rawHeaders.length should not exceed maxHeadersCount * 2. The limit exists to cap header processing.

What do you see instead?

With maxHeadersCount = 50 (limit of 100 elements), rawHeaders.length is 124 - exceeding by 24.

The issue is in parserOnHeaders (lib/_http_common.js:58-65). The check _headers.length < maxHeaderPairs passes before a flush, but the flush can add up to 64 elements at once, overshooting the limit. req.headers is correctly clamped, but rawHeaders receives the full array reference.

Additional information

Suggested fix - cap each flush to remaining capacity:

function parserOnHeaders(headers, url) {
  if (this.maxHeaderPairs <= 0) {
    this._headers.push(...headers);
  } else {
    const remaining = this.maxHeaderPairs - this._headers.length;
    if (remaining > 0) {
      this._headers.push(...headers.slice(0, remaining));
    }
  }
  this._url += url;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    httpIssues or PRs related to the http subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions