websockets/ws · error · Error
Unexpected or invalid parameter "client_max_window_bits"
Error message
Unexpected or invalid parameter "client_max_window_bits"
What it means
Thrown by `PerMessageDeflate.acceptAsClient()` when the server's permessage-deflate response contains a `client_max_window_bits` value the client cannot accept: either the client set `clientMaxWindowBits: false` (it does not want this parameter) but the server sent one, or the server sent a value larger than the number the client advertised (`params.client_max_window_bits > clientMaxWindowBits`). RFC 7692 forbids the server from raising the window above the client's offer.
Solutions
- Match the client's `clientMaxWindowBits` to (or above) what the server will respond with, or omit it to advertise the default.
- Fix the server so it never responds with a `client_max_window_bits` larger than the client's offer.
- Disable compression on the client (`perMessageDeflate: false`) if the server cannot be changed.
Example fix
// before
const ws = new WebSocket(url, {
perMessageDeflate: { clientMaxWindowBits: 10 }
});
// server responds with client_max_window_bits=15 -> throws
// after
const ws = new WebSocket(url, {
perMessageDeflate: { clientMaxWindowBits: 15 }
}); Defensive patterns
Strategy: try-catch
Try / catch
try {
perMessageDeflate.accept(serverResponseOffers);
} catch (err) {
if (/client_max_window_bits/.test(err.message)) {
// Server's window-size response is incompatible with the client's offer.
reconnectWithoutCompression(url);
return;
}
throw err;
} Prevention
- Either omit `clientMaxWindowBits` on the client (advertise the default) or set it to a value the server will accept.
- Ensure the server never responds with a window larger than the client's offer (RFC 7692).
- Have a `perMessageDeflate: false` fallback path when the server is non-conformant.
When it happens
Trigger: Client created with `new WebSocket(url, { perMessageDeflate: { clientMaxWindowBits: 10 } })` against a server that responds with `client_max_window_bits: 15`; or a client with `clientMaxWindowBits: false` against a server that includes the parameter anyway.
Common situations: Server bug/proxy that inflates the window size in the response; mismatched compression policies across a load balancer; a peer that does not honor RFC 7692 negotiation rules.
Related errors
- None of the extension offers can be accepted
- Unexpected parameter "client_no_context_takeover"
- Invalid value for parameter
- Parameter " " must have only a single value
- Unknown parameter
AI-assisted analysis of websockets/ws@c791e707ea (2026-08-06).
Data as JSON: /api/errors/3698fc17f5af4f41.
Report an issue: GitHub.
Appendix: source
Thrown at lib/permessage-deflate.js:231
const params = response[0];
if (
this._options.clientNoContextTakeover === false &&
params.client_no_context_takeover
) {
throw new Error('Unexpected parameter "client_no_context_takeover"');
}
if (!params.client_max_window_bits) {
if (typeof this._options.clientMaxWindowBits === 'number') {
params.client_max_window_bits = this._options.clientMaxWindowBits;
}
} else if (
this._options.clientMaxWindowBits === false ||
(typeof this._options.clientMaxWindowBits === 'number' &&
params.client_max_window_bits > this._options.clientMaxWindowBits)
) {
throw new Error(
'Unexpected or invalid parameter "client_max_window_bits"'
);
}
return params;
}
/**
* Normalize parameters.
*
* @param {Array} configurations The extension negotiation offers/reponse
* @return {Array} The offers/response with normalized parameters
* @private
*/
normalizeParams(configurations) {
configurations.forEach((params) => {
Object.keys(params).forEach((key) => {
let value = params[key];View on GitHub (pinned to c791e707ea)