websockets/ws · error · Error

None of the extension offers can be accepted

Error message

None of the extension offers can be accepted

What it means

Thrown by PerMessageDeflate.acceptAsServer() (permessage-deflate.js:178-179) when none of the client's offered permessage-deflate configurations satisfy the server's configured constraints. The server iterates each offered config and rejects it if it conflicts with serverNoContextTakeover=false, serverMaxWindowBits limits, or clientMaxWindowBits requirements. If every offer fails these checks, the negotiation aborts.

Source

Thrown at lib/permessage-deflate.js:179

    const accepted = offers.find((params) => {
      if (
        (opts.serverNoContextTakeover === false &&
          params.server_no_context_takeover) ||
        (params.server_max_window_bits &&
          (opts.serverMaxWindowBits === false ||
            (typeof opts.serverMaxWindowBits === 'number' &&
              opts.serverMaxWindowBits > params.server_max_window_bits))) ||
        (typeof opts.clientMaxWindowBits === 'number' &&
          !params.client_max_window_bits)
      ) {
        return false;
      }

      return true;
    });

    if (!accepted) {
      throw new Error('None of the extension offers can be accepted');
    }

    if (opts.serverNoContextTakeover) {
      accepted.server_no_context_takeover = true;
    }
    if (opts.clientNoContextTakeover) {
      accepted.client_no_context_takeover = true;
    }
    if (typeof opts.serverMaxWindowBits === 'number') {
      accepted.server_max_window_bits = opts.serverMaxWindowBits;
    }
    if (typeof opts.clientMaxWindowBits === 'number') {
      accepted.client_max_window_bits = opts.clientMaxWindowBits;
    } else if (
      accepted.client_max_window_bits === true ||
      opts.clientMaxWindowBits === false
    ) {
      delete accepted.client_max_window_bits;

View on GitHub (pinned to ae1de54330)

Solutions

  1. Relax the server's perMessageDeflate constraints — e.g. remove clientMaxWindowBits as a number, or set serverNoContextTakeover to undefined instead of requiring it.
  2. Adjust the client's offer to include parameters the server requires (client_max_window_bits, server_no_context_takeover, etc.).
  3. Set perMessageDeflate: false on the server to disable compression entirely if compatibility cannot be achieved.
  4. Log the server options and the received client offers side-by-side to identify the conflicting parameter.

Example fix

// before — server requires a client_max_window_bits the client never offers
new WebSocketServer({ port: 8080, perMessageDeflate: { clientMaxWindowBits: 12 } });

// after — let the server accept offers without forcing client window bits
new WebSocketServer({ port: 8080, perMessageDeflate: {} });
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check: verify at least one client offer is compatible before calling accept()
function canAccept(serverOpts, offers) {
  return offers.some((params) => {
    if (serverOpts.serverNoContextTakeover === false && params.server_no_context_takeover) return false;
    if (params.server_max_window_bits &&
        (serverOpts.serverMaxWindowBits === false ||
         (typeof serverOpts.serverMaxWindowBits === 'number' &&
          serverOpts.serverMaxWindowBits > params.server_max_window_bits))) return false;
    if (typeof serverOpts.clientMaxWindowBits === 'number' && !params.client_max_window_bits) return false;
    return true;
  });
}

const pmd = new PerMessageDeflate({ ...serverOpts, isServer: true });
if (canAccept(serverOpts, clientOffers)) {
  pmd.accept(clientOffers);
}

Try / catch

try {
  perMessageDeflate.accept(offers);
} catch (err) {
  if (err.message === 'None of the extension offers can be accepted') {
    // Proceed without compression — connection stays open, just uncompressed
    console.warn('Compression negotiation failed; continuing without permessage-deflate.');
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: A WebSocketServer with perMessageDeflate configured (e.g. serverNoContextTakeover, serverMaxWindowBits, or clientMaxWindowBits as a number) receives a client offer that violates every constraint. For example, the server requires client_max_window_bits but the client omits it, or the server sets serverMaxWindowBits to a number and the client offers a larger value in every configuration.

Common situations: A server operator tightens compression settings (e.g. sets clientMaxWindowBits to a specific number) that are incompatible with a client's defaults. A custom client sends offers that don't match the server's policy. Mismatched perMessageDeflate option expectations between client and server.

Related errors


AI-assisted analysis of websockets/ws@ae1de54330 (2026-08-03). Data as JSON: /data/errors/439c93bee3957e46.json. Report an issue: GitHub.