How to fix Error: Invalid HTTP version (unsupported protocol) in Node.js

Node.jsINTERMEDIATEMEDIUMUpdated Dec 22, 2025ยท 151 views

This error occurs when a Node.js HTTP client receives an HTTP response with a version string that the parser cannot recognize or does not support. It typically indicates a protocol mismatch, malformed server response, or incompatibility with an intermediary like a proxy or load balancer.

Quick fix

Fixes Error: Invalid HTTP version (unsupported protocol)

# Test HTTP/1.1 (default)
curl -v http://example.com

# Test HTTP/2
curl --http2 -v https://example.com

# Test HTTP/3 (QUIC)
curl --http3 -v https://example.com

# Check response headers and protocol version
curl -i http://example.com | head -20
  1. Verify the HTTP version expected by the server
  2. Check your Node.js HTTP client configuration
  3. Disable HTTP/2 support if encountering proxy issues
  4. Check proxy and load balancer configuration
node.js โ€” error
# Test HTTP/1.1 (default)
curl -v http://example.com
# Test HTTP/2
curl --http2 -v https://example.com
# Test HTTP/3 (QUIC)
curl --http3 -v https://example.com
# Check response headers and protocol version
curl -i http://example.com | head -20
Error: Invalid HTTP version (unsupported protocol)

What this error means

The "Invalid HTTP version" error is raised when Node.js's HTTP parser encounters an unrecognized HTTP version string in a server response or request line. The HTTP specification defines valid versions like HTTP/1.0, HTTP/1.1, HTTP/2, and HTTP/3, but servers or proxies may return malformed versions like "HTTP/2.0" (invalid), "HTTP/1" (incomplete), or corrupted version strings. Node.js validates HTTP versions strictly during parsing. When the parser encounters a version it cannot understand or that doesn't conform to the HTTP specification, it throws this error to prevent processing a potentially malicious or corrupted message. This error is distinct from protocol mismatch errors (using http:// with an HTTPS endpoint) and usually indicates either a server configuration issue, proxy misconfiguration, or data corruption during transmission. It often surfaces in proxy environments, CDN requests, or connections through middleware that may rewrite HTTP headers.

Typical symptoms

  • HTTP requests fail with "Error: Invalid HTTP version (unsupported protocol)"
  • Requests work when accessing the server directly but fail through a proxy
  • Only specific endpoints or request types trigger the error
  • Error occurs intermittently or only with certain HTTP versions
  • Works in development but fails when deploying through a load balancer or CDN
  • Upstream proxy server is returning malformed HTTP responses
  • Mixed use of HTTP and HTTPS in request chains causes parsing failures

Common causes

  1. Server or proxy returning malformed HTTP version strings (e.g., "HTTP/2.0" instead of "HTTP/2")
  2. Protocol mismatch between client expectation and server response
  3. Proxy or load balancer injecting or rewriting invalid HTTP headers
  4. Network corruption or incomplete HTTP response transmission
  5. Node.js HTTP client library attempting to use an unsupported HTTP version
  6. Misconfigured reverse proxy (nginx, Apache, HAProxy) returning invalid headers
  7. SSL/TLS proxy or man-in-the-middle device corrupting HTTP headers
  8. Legacy or custom HTTP server implementation returning non-standard version strings

How to fix "Error: Invalid HTTP version (unsupported protocol)"

1Verify the HTTP version expected by the server

Check what HTTP version your target server supports using curl or other tools:

bash
# Test HTTP/1.1 (default)
curl -v http://example.com

# Test HTTP/2
curl --http2 -v https://example.com

# Test HTTP/3 (QUIC)
curl --http3 -v https://example.com

# Check response headers and protocol version
curl -i http://example.com | head -20

The first line of the response should show a valid HTTP version like "HTTP/1.1 200 OK" or "HTTP/2 200". If you see an invalid format, the server is misconfigured.

2Check your Node.js HTTP client configuration

Verify that your Node.js code is using compatible HTTP versions:

javascript
const http = require('http');
const https = require('https');

// Standard HTTP/1.1 request (default)
const req = https.get('https://example.com', (res) => {
  console.log(`Protocol: ${res.httpVersion}`); // Should be "1.1" or "2.0"
  res.pipe(process.stdout);
});

req.on('error', (err) => {
  console.error('Request error:', err.message);
});

Ensure you're using http for HTTP URLs and https for HTTPS URLs. Mixing protocols causes parsing issues.

3Disable HTTP/2 support if encountering proxy issues

If the error occurs when routing through a proxy, try disabling HTTP/2:

javascript
const https = require('https');

const options = {
  hostname: 'example.com',
  port: 443,
  path: '/',
  method: 'GET',
  // Disable HTTP/2 for compatibility with some proxies
  http2: false,
};

const req = https.request(options, (res) => {
  console.log(`Status: ${res.statusCode}`);
  res.on('data', (chunk) => {
    process.stdout.write(chunk);
  });
});

req.on('error', (err) => {
  console.error('Request error:', err.message);
});

req.end();

Some older proxies don't properly handle HTTP/2, causing them to return malformed version strings.

4Check proxy and load balancer configuration

If requests fail when routing through a proxy, review the proxy settings:

For nginx reverse proxy, ensure valid HTTP version handling:

nginx
upstream backend {
  server backend-server:3000;
  # Ensure proxy passes valid HTTP versions
}

server {
  listen 80;
  server_name example.com;

  location / {
    proxy_pass http://backend;
    # Explicitly set HTTP version
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

Check that the proxy is not rewriting or corrupting the HTTP version header.

5Update to latest Node.js version

HTTP parsing in Node.js improves with each version. Update to the latest LTS or current version:

bash
# Check current Node.js version
node --version

# Update Node.js using nvm (recommended)
nvm install --lts
nvm use --lts

# Or update via your package manager
# macOS
brew upgrade node

# Ubuntu/Debian
sudo apt update && sudo apt upgrade nodejs

# Verify update
node --version

Newer versions have better error handling and compatibility with various proxy configurations.

6Implement error handling and fallback logic

Handle this error gracefully and retry with different HTTP versions:

javascript
const https = require('https');

async function fetchWithFallback(url, options = {}) {
  const httpVersions = ['1.1', '1.0']; // Fallback sequence

  for (const version of httpVersions) {
    try {
      console.log(`Attempting with HTTP/${version}...`);

      const opts = {
        ...options,
        http2: version !== '1.0' && version !== '1.1',
      };

      return await new Promise((resolve, reject) => {
        https.get(url, opts, (res) => {
          let data = '';
          res.on('data', (chunk) => data += chunk);
          res.on('end', () => resolve(data));
        }).on('error', reject);
      });
    } catch (err) {
      console.error(`Failed with HTTP/${version}: ${err.message}`);
      if (version === httpVersions[httpVersions.length - 1]) {
        throw err; // All versions failed
      }
    }
  }
}

fetchWithFallback('https://example.com')
  .then((data) => console.log('Success:', data))
  .catch((err) => console.error('All attempts failed:', err.message));

This approach automatically retries with different HTTP versions if the server is misconfigured.

7Inspect network traffic to diagnose the issue

Use network debugging tools to see the exact HTTP version being returned:

bash
# Capture HTTP traffic with tcpdump
sudo tcpdump -i any -A 'tcp port 443 or tcp port 80' | grep -i 'HTTP'

# Or use Wireshark for GUI packet inspection
wireshark

# Use curl with maximum verbosity
curl -vvv http://example.com 2>&1 | head -40

# Check for Node.js HTTP debug logs
NODE_DEBUG=http node your-script.js 2>&1 | head -50

Look for the exact response line. Valid responses should look like:
- HTTP/1.1 200 OK
- HTTP/2 200
- HTTP/1.0 200 OK

Invalid responses might show corrupted version strings like HTTP/2.0 or HTTP without a version.

Advanced notes

Understanding HTTP Version Parsing in Node.js

Node.js uses the llhttp library (successor to http-parser) for HTTP parsing. The parser strictly validates HTTP versions against the HTTP specification. Valid versions include:

- HTTP/1.0 (deprecated but still supported)
- HTTP/1.1 (most common)
- HTTP/2 (or h2)
- HTTP/3 (QUIC, newer)

The parser rejects anything that doesn't match the pattern, including:
- HTTP/2.0 (should be HTTP/2)
- HTTP/1 (incomplete, needs .0 or .1)
- HTTPS/1.1 (HTTPS is a protocol, not a version)
- h2c (HTTP/2 Cleartext) over non-encrypted connections may also cause issues

Proxy-Specific Issues

Corporate proxies, especially older ones or those with SSL inspection, may:
- Rewrite HTTP version headers
- Return malformed upgrade responses
- Fail to properly translate between HTTP versions
- Inject custom headers that break parsing

Solutions:
1. Bypass the proxy if possible for specific requests
2. Configure the proxy to use HTTP/1.1 exclusively
3. Use a proxy authentication library if credentials are needed
4. Contact proxy administrator to update configuration

TLS/SSL Interception Problems

Some security appliances intercept HTTPS traffic and re-encrypt it, potentially corrupting HTTP version information. If the error only occurs with HTTPS:

javascript
// Allow self-signed certificates from intercepting proxy (development only)
const https = require('https');

const agent = new https.Agent({
  rejectUnauthorized: false, // WARNING: For testing only!
});

https.get('https://example.com', { agent }, (res) => {
  console.log('Success');
});

In production, work with your security team to configure proper certificate chains.

HTTP/2 Server Push and Version Mismatches

If using HTTP/2 server push, ensure your client properly handles it:

javascript
const spdy = require('spdy'); // For HTTP/2 support

const req = spdy.request(options, (res) => {
  res.on('push', (err, pushedRes) => {
    if (err) {
      console.error('Push error:', err.message);
      return;
    }
    console.log('Received push:', pushedRes.url);
  });
});

Ensure both client and server negotiate the same protocol version in TLS handshake.

Load Balancer Configuration

For applications behind load balancers (AWS ELB, Google Load Balancer, etc.):

- AWS ALB: Ensure HTTP/2 is enabled if clients expect it
- Google Cloud Load Balancer: Check HTTP version settings
- Kubernetes Ingress: Verify ingress controller HTTP version support

Contact your hosting provider's support if upgrading HTTP versions on load balancers.

Frequently asked questions

What does "Error: Invalid HTTP version (unsupported protocol)" mean?
js's HTTP parser encounters an unrecognized HTTP version string in a server response or request line. 0" (invalid), "HTTP/1" (incomplete), or corrupted version strings. js validates HTTP versions strictly during parsing.
How do I fix "Error: Invalid HTTP version (unsupported protocol)"?
This error occurs when a Node.js HTTP client receives an HTTP response with a version string that the parser cannot recognize or does not support. It typically indicates a protocol mismatch, malformed server response, or incompatibility with an intermediary like a proxy or load balancer.
What causes "Error: Invalid HTTP version (unsupported protocol)"?
Server or proxy returning malformed HTTP version strings (e.g., "HTTP/2.0" instead of "HTTP/2") Protocol mismatch between client expectation and server response Proxy or load balancer injecting or rewriting invalid HTTP headers
Is the "Error: Invalid HTTP version (unsupported protocol)" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading