{"record":{"id":"73b0fdbb2ff44098","repo":"nodejs/node","slug":"too-many-content-encodings-in-response-parts-le","errorCode":null,"errorMessage":"too many content-encodings in response: ${parts.length}, maximum allowed is ${maxContentEncodings}","messagePattern":"too many content-encodings in response: (.+?), maximum allowed is (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/interceptor/decompress.js","lineNumber":75,"sourceCode":"    if (this.#skipErrorResponses && statusCode >= 400) return true\n    return false\n  }\n\n  /**\n   * Creates a chain of decompressors for multiple content encodings\n   *\n   * @param {string} encodings - Comma-separated list of content encodings\n   * @returns {Array<DecompressorStream>} - Array of decompressor streams\n   * @throws {Error} - If the number of content-encodings exceeds the maximum allowed\n   */\n  #createDecompressionChain (encodings) {\n    const parts = encodings.split(',')\n\n    // Limit the number of content-encodings to prevent resource exhaustion.\n    // CVE fix similar to urllib3 (GHSA-gm62-xv2j-4w53) and curl (CVE-2022-32206).\n    const maxContentEncodings = 5\n    if (parts.length > maxContentEncodings) {\n      throw new Error(`too many content-encodings in response: ${parts.length}, maximum allowed is ${maxContentEncodings}`)\n    }\n\n    /** @type {DecompressorStream[]} */\n    const decompressors = []\n\n    for (let i = parts.length - 1; i >= 0; i--) {\n      const encoding = parts[i].trim()\n      if (!encoding) continue\n\n      if (!supportedEncodings[encoding]) {\n        decompressors.length = 0 // Clear if unsupported encoding\n        return decompressors // Unsupported encoding\n      }\n\n      decompressors.push(supportedEncodings[encoding]())\n    }\n\n    return decompressors","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/interceptor/decompress.js#L57-L93","documentation":"Thrown by the decompress() interceptor's #createDecompressionChain when the response Content-Encoding header contains more than 5 comma-separated encodings. This is a deliberate resource-exhaustion guard mirroring fixes for urllib3 GHSA-gm62-xv2j-4w53 and curl CVE-2022-32206: deeply nested encodings can be used to amplify a small response into huge CPU/memory use, so the interceptor caps the chain length at 5.","triggerScenarios":"A server (often malicious or misconfigured) returns a Content-Encoding header like 'gzip, gzip, gzip, gzip, gzip, gzip' (>5 entries). The decompress interceptor throws synchronously while setting up the decompression pipeline.","commonSituations":"Security testing/fuzzing; buggy compression middleware that stacks encodings; adversarial origins; intermediary that appends encodings on each hop.","solutions":["Treat the response as untrusted: do not use the decompress interceptor for that origin, or fix the origin to send a single sane encoding.","If you control the server, ensure Content-Encoding has at most one (or a small, valid) layer.","Catch the error per-request and fall back to consuming the raw (still-encoded) body or failing the request explicitly."],"exampleFix":"// before\nclient.compose(interceptors.decompress())\n// a response with Content-Encoding: gzip, gzip, gzip, gzip, gzip, gzip throws\n\n// after\n// exclude the offending origin from decompression, or handle the error:\ntry {\n  await client.request(opts)\n} catch (e) {\n  if (e.message.startsWith('too many content-encodings')) {\n    // consume raw body or reject the response\n    throw new Error('Refusing suspicious response from ' + opts.origin)\n  }\n  throw e\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await client.request(opts) } catch (e) { if (e.message.startsWith('too many content-encodings')) { throw new Error(`Refusing suspicious response from ${opts.origin}`) } else throw e }","preventionTips":["Do not enable the decompress interceptor for untrusted origins.","Ensure your origin sends at most one Content-Encoding layer.","Treat deeply nested encodings as an attack signal."],"tags":["undici","http","decompress","security","content-encoding","resource-exhaustion","cve"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}