nodejs/node · error · InvalidArgumentError

UND_ERR_INVALID_ARG

UND_ERR_INVALID_ARG

Error message

maxCachedSessions must be a positive integer or zero

What it means

Thrown by buildConnector (the TLS/connection factory used by undici's Client and Pool) when maxCachedSessions is provided but is not an integer >= 0. maxCachedSessions controls how many resumed TLS sessions are cached per host; the guard is `maxCachedSessions != null && (!Number.isInteger(...) || value < 0)`.

Source

Thrown at deps/undici/src/lib/core/connect.js:64

          this._sessionCache.delete(key)
          return
        }
      }

      const oldest = this._sessionCache.keys().next()
      if (!oldest.done) {
        this._sessionCache.delete(oldest.value)
      }
    }

    this._sessionCache.set(sessionKey, new WeakRef(session))
    this._sessionRegistry.register(session, sessionKey)
  }
}

function buildConnector ({ allowH2, preferH2, useH2c, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) {
  if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) {
    throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero')
  }

  const options = { path: socketPath, ...opts }
  const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions)
  timeout = timeout == null ? 10e3 : timeout
  allowH2 = allowH2 != null ? allowH2 : true
  return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) {
    let socket
    if (protocol === 'https:') {
      if (!tls) {
        tls = require('node:tls')
      }
      servername = servername || options.servername || util.getServerName(host) || null

      const sessionKey = servername || hostname
      assert(sessionKey)

      const session = customSession || sessionCache.get(sessionKey) || null

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Pass an integer >= 0: new Client(url, { connect: { maxCachedSessions: 100 } }).
  2. To disable session caching, pass 0 (not a negative number).
  3. Coerce from config: Number.parseInt(process.env.TLS_SESSION_CACHE, 10).
  4. Omit the option entirely to take the default of 100.

Example fix

// before
new Client(url, { connect: { maxCachedSessions: process.env.TLS_CACHE } })
// after
const n = Number.parseInt(process.env.TLS_CACHE, 10)
new Client(url, { connect: { maxCachedSessions: Number.isNaN(n) ? 100 : n } })
Defensive patterns

Strategy: validation

Validate before calling

function coerceMaxCachedSessions(v) {
  const n = Number(v)
  if (!Number.isInteger(n) || n < 0) {
    throw new TypeError('maxCachedSessions must be an integer >= 0')
  }
  return n
}

Type guard

function isValidMaxCachedSessions(v) {
  return v == null || (typeof v === 'number' && Number.isInteger(v) && v >= 0)
}

Prevention

When it happens

Trigger: Passing maxCachedSessions as a float (1.5), a negative number, a string ('100'), NaN, Infinity, or a BigInt. Note the message says 'positive integer or zero' but 0 is accepted; only negative or non-integer values throw.

Common situations: Setting maxCachedSessions via env var as a string; accidentally using a fractional value; disabling caching by passing -1 instead of 0; misreading the message as 'must be > 0'.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/f142959c5ac7a744. Report an issue: GitHub.