How to fix TypeError: Invalid header value provided (header contains invalid characters) in Node.js

Node.jsINTERMEDIATEHIGHUpdated Dec 9, 2025· 194 views

This error occurs when you attempt to set an HTTP header with a value containing characters that violate HTTP header specifications. Node.js strictly validates header values to prevent header injection attacks and protocol violations.

Quick fix

Fixes ERR_HTTP_INVALID_HEADER_VALUE

const http = require('http');

// Unsafe - user input directly in header
const req = http.request({
  hostname: 'example.com',
  headers: {
    'X-Custom': userInput  // DANGEROUS!
  }
});

// Safe - validate first
function isValidHeaderValue(value) {
  // Allow only printable ASCII + tabs (0x20-0x7E and 0x09)
  return /^[	\x20-\x7E]*$/.test(value);
}

const sanitized = String(userInput).trim();
if (!isValidHeaderValue(sanitized)) {
  throw new Error('Invalid header value');
}

const req = http.request({
  hostname: 'example.com',
  headers: {
    'X-Custom': sanitized  // Safe
  }
});
  1. Validate and sanitize header values before setting
  2. Remove newlines and control characters from user input
  3. Use URL encoding for header values containing special characters
  4. Use Buffer.toString("base64") for binary or complex data in headers
node.js — error
const http = require('http');
// Unsafe - user input directly in header
const req = http.request({
hostname: 'example.com',
headers: {
'X-Custom': userInput // DANGEROUS!
}
});
// Safe - validate first
function isValidHeaderValue(value) {
// Allow only printable ASCII + tabs (0x20-0x7E and 0x09)
return /^[ \x20-\x7E]*$/.test(value);
}
const sanitized = String(userInput).trim();
if (!isValidHeaderValue(sanitized)) {
throw new Error('Invalid header value');
}
const req = http.request({
hostname: 'example.com',
headers: {
'X-Custom': sanitized // Safe
}
});
TypeError: Invalid header value provided (header contains invalid characters)

What this error means

The "Invalid header value" error is thrown by Node.js when you try to set an HTTP response or request header with a value containing illegal characters. HTTP headers must conform to strict RFC 7230 specifications—they can only contain printable ASCII characters (values 0x20-0x7E) and certain control characters. Node.js enforces this validation to prevent: 1. **Header Injection Attacks**: Where attackers inject newlines (\r\n) to add fake headers 2. **Protocol Violations**: Values with invalid characters break HTTP parsing 3. **Security Issues**: Certain character combinations could bypass security filters When you violate these rules, Node.js throws a TypeError with details about the offending header and character.

Typical symptoms

  • TypeError thrown when setting response headers with res.setHeader()
  • Request headers fail when using http.request() or fetch()
  • Error message specifies which header and what characters are invalid
  • Applications crash if error is not caught in header-setting code
  • Issues occur after user input is used to construct header values
  • Problem arises when dynamically building headers from variables
  • Headers with URLs, file paths, or special characters trigger the error

Common causes

  1. Header value contains newline characters (\n, \r, \r\n) enabling header injection
  2. Value has non-ASCII characters or control characters forbidden in headers
  3. Unescaped user input is directly used as a header value
  4. URLs, file paths, or other unvalidated data used in header values
  5. Header value exceeds maximum length limits (8KB per Node.js)
  6. Attempting to set headers after response has started being sent
  7. Using binary data or non-string types in header values
  8. Custom header names contain invalid characters (colons, spaces, etc.)

How to fix "TypeError: Invalid header value provided (header contains invalid characters)"

1Validate and sanitize header values before setting

Always validate header values to ensure they contain only safe characters:

javascript
const http = require('http');

// Unsafe - user input directly in header
const req = http.request({
  hostname: 'example.com',
  headers: {
    'X-Custom': userInput  // DANGEROUS!
  }
});

// Safe - validate first
function isValidHeaderValue(value) {
  // Allow only printable ASCII + tabs (0x20-0x7E and 0x09)
  return /^[	\x20-\x7E]*$/.test(value);
}

const sanitized = String(userInput).trim();
if (!isValidHeaderValue(sanitized)) {
  throw new Error('Invalid header value');
}

const req = http.request({
  hostname: 'example.com',
  headers: {
    'X-Custom': sanitized  // Safe
  }
});
2Remove newlines and control characters from user input

Strip dangerous characters like newlines that enable header injection:

javascript
const http = require('http');
const express = require('express');
const app = express();

app.get('/api/proxy', (req, res) => {
  // Unsafe - user input directly in header
  // const userAgent = req.query.ua;  // Could be: "test\r\nX-Injected: value"

  // Safe - remove newlines and control characters
  const userAgent = String(req.query.ua || '')
    .replace(/[\r\n]/g, '')  // Remove newlines
    .replace(/[^\x20-\x7E\t]/g, '');  // Keep only valid chars

  const options = {
    hostname: 'external-api.com',
    headers: {
      'User-Agent': userAgent || 'MyApp/1.0'  // Safe default
    }
  };

  const request = http.request(options, (response) => {
    res.writeHead(response.statusCode, response.headers);
    response.pipe(res);
  });

  request.on('error', (err) => {
    res.status(500).json({ error: err.message });
  });

  request.end();
});
3Use URL encoding for header values containing special characters

For headers that legitimately need special characters, use URL encoding:

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

// Example: passing JSON or complex data in headers
const data = {
  userId: 123,
  action: 'view',
  timestamp: Date.now()
};

// Unsafe - raw JSON has characters that violate headers
// const header = JSON.stringify(data);  // Contains {, }, :, ", etc.

// Safe - encode as URL parameter
const encoded = querystring.stringify(data);
// Result: "userId=123&action=view&timestamp=1234567890"

const options = {
  hostname: 'api.example.com',
  path: '/data',
  headers: {
    'X-Data': encoded  // Safe - only alphanumeric, =, &
  }
};

const req = http.request(options, (res) => {
  console.log('Status:', res.statusCode);
});

req.end();

// On the receiving end, decode:
const received = querystring.parse(req.headers['x-data']);
console.log(received.userId);  // "123"
4Use Buffer.toString("base64") for binary or complex data in headers

For headers containing binary or complex data, encode as Base64:

javascript
const http = require('http');

// Complex data that might contain invalid characters
const binaryData = Buffer.from('\x00\x01\x02\x03', 'binary');

// Unsafe - setting raw binary data
// headers: { 'X-Data': binaryData }  // Will fail

// Safe - encode to base64
const encoded = binaryData.toString('base64');

const options = {
  hostname: 'api.example.com',
  headers: {
    'X-Data': encoded,  // "AAEQAQ=="
    'X-Data-Encoding': 'base64'
  }
};

const req = http.request(options, (res) => {
  console.log('Response received');
});

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

req.end();

// On the receiving end:
app.get('/api/data', (req, res) => {
  if (req.headers['x-data-encoding'] === 'base64') {
    const decoded = Buffer.from(req.headers['x-data'], 'base64');
    console.log(decoded);  // Original binary data
  }
  res.send('OK');
});
5Catch and handle header validation errors

Wrap header-setting code in try-catch blocks to gracefully handle validation errors:

javascript
const http = require('http');

function setHeaderSafely(res, name, value, defaultValue = '') {
  try {
    // Validate before setting
    const sanitized = String(value).trim();

    // Check for newlines
    if (sanitized.includes('\n') || sanitized.includes('\r')) {
      console.warn(`Header '${name}' contains newlines, using default`);
      res.setHeader(name, defaultValue);
      return;
    }

    // Try to set
    res.setHeader(name, sanitized);
  } catch (err) {
    console.error(`Failed to set header '${name}': ${err.message}`);
    // Use safe default instead of crashing
    if (defaultValue) {
      res.setHeader(name, defaultValue);
    }
  }
}

// Usage in Express
const express = require('express');
const app = express();

app.get('/api/data', (req, res) => {
  setHeaderSafely(res, 'X-User-ID', req.query.userId, 'unknown');
  setHeaderSafely(res, 'X-Request-ID', req.headers['x-request-id']);

  res.json({ status: 'ok' });
});
6Use a library for HTTP header validation

Consider using libraries that handle header validation safely:

javascript
// Using express-validator for header validation
const express = require('express');
const { validationResult, header } = require('express-validator');

const app = express();

// Validate custom headers on incoming requests
app.get('/api/data',
  header('X-Custom-Header').trim().escape().optional(),
  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    res.json({ received: req.headers['x-custom-header'] });
  }
);

// Using a sanitization utility
function createSafeHeader(name, value) {
  // Remove control characters and newlines
  const sanitized = String(value)
    .replace(/[\r\n]/g, '')  // Remove newlines
    .replace(/[^\x20-\x7E\t]/g, '')  // Keep only valid ASCII
    .trim();

  if (!sanitized) {
    throw new Error(`Header '${name}' became empty after sanitization`);
  }

  if (sanitized.length > 8000) {
    throw new Error(`Header '${name}' exceeds maximum length`);
  }

  return { name, value: sanitized };
}

module.exports = { createSafeHeader };

Advanced notes

RFC 7230 Header Compliance: HTTP headers are defined by RFC 7230 and must contain only token characters (alphanumeric + certain symbols like hyphen) for the name, and field-content (printable ASCII + spaces + tabs) for the value. Node.js strictly enforces this to comply with the specification and prevent security issues.

Header Injection Prevention: This validation is crucial for preventing HTTP Response Splitting attacks (CVE-2009-1891) where attackers inject \r\n sequences to add fake headers or inject content. Strict header validation in Node.js 14+ makes these attacks impossible.

Maximum Header Sizes: Node.js has built-in limits on header size (8KB total per header). Some headers like Cookie, User-Agent, or Authorization can legitimately exceed this. For large values, consider alternative mechanisms like POST body parameters or token-based sessions.

Framework Differences: Express.js passes through Node.js's native validation, so res.setHeader() enforces the same rules. Other frameworks like Fastify or Hapi have similar enforcement. Always validate early in your data pipeline.

Common Invalid Characters: Besides newlines (\r, \n), be cautious with:
- Control characters (0x00-0x1F except tab/0x09)
- Non-ASCII characters (>0x7F)
- Unescaped special characters in unquoted values

Best Practice: Treat all external input (query params, user input, database values) as untrusted. Always validate and sanitize before using in HTTP headers. Consider using allowlists (specific character sets) rather than blocklists.

Testing: Test header validation by attempting to inject newlines in your unit tests: 'value\r\nX-Injected: true'. If your code doesn't reject this, it's vulnerable. Use tools like BURP Suite for security testing.

Frequently asked questions

What does "ERR_HTTP_INVALID_HEADER_VALUE" mean?
js when you try to set an HTTP response or request header with a value containing illegal characters. HTTP headers must conform to strict RFC 7230 specifications—they can only contain printable ASCII characters (values 0x20-0x7E) and certain control characters. js enforces this validation to prevent: 1.
How do I fix "ERR_HTTP_INVALID_HEADER_VALUE"?
This error occurs when you attempt to set an HTTP header with a value containing characters that violate HTTP header specifications. Node.js strictly validates header values to prevent header injection attacks and protocol violations.
What causes "ERR_HTTP_INVALID_HEADER_VALUE"?
Header value contains newline characters (\n, \r, \r\n) enabling header injection Value has non-ASCII characters or control characters forbidden in headers Unescaped user input is directly used as a header value
Is the "ERR_HTTP_INVALID_HEADER_VALUE" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading