{"id":"38e1812b62b89daa","repo":"guzzle/guzzle","slug":"the-multiplex-request-option-cannot-be-multiplex","errorCode":null,"errorMessage":"The \"multiplex\" request option cannot be Multiplexing::NONE on a CurlMultiHandler that permits multiplexing and requires persistent transport sharing; set the \"multiplex\" client or CurlMultiHandler constructor option to Multiplexing::NONE, or use TransportSharing::PERSISTENT_PREFER.","messagePattern":"The \"multiplex\" request option cannot be Multiplexing::NONE on a CurlMultiHandler that permits multiplexing and requires persistent transport sharing; set the \"multiplex\" client or CurlMultiHandler constructor option to Multiplexing::NONE, or use TransportSharing::PERSISTENT_PREFER\\.","errorType":"validation","errorClass":"GuzzleHttp\\Exception\\InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Handler/CurlMultiHandler.php","lineNumber":432,"sourceCode":"            return;\n        }\n\n        if (!$this->ownsFactory) {\n            throw new InvalidArgumentException('The \"multiplex\" request option can only be Multiplexing::NONE on a CurlMultiHandler with a custom \"handle_factory\" when the handler\\'s own \"multiplex\" option is Multiplexing::NONE, because the guarantee is enforced against the native easy handle the factory controls.');\n        }\n\n        $version = $easy->request->getProtocolVersion();\n        if ('1.0' !== $version && '1.1' !== $version) {\n            throw new InvalidArgumentException('The \"multiplex\" request option can only be Multiplexing::NONE for an HTTP/1.x request on a CurlMultiHandler that permits multiplexing; set the \"multiplex\" client or CurlMultiHandler constructor option to Multiplexing::NONE to disable multiplexing for every transfer, or send the request with its \"version\" option set to \"1.1\".');\n        }\n\n        if (null !== $this->shareHandleState && TransportSharing::PERSISTENT_REQUIRE === $this->shareHandleState->mode) {\n            // The matcher-window hardening below may force a fresh\n            // connection, which required persistent sharing forbids because\n            // it disables connection reuse (CurlFactory applies the same\n            // rule to the raw option); rejected on every runtime so\n            // acceptance stays version-independent.\n            throw new InvalidArgumentException('The \"multiplex\" request option cannot be Multiplexing::NONE on a CurlMultiHandler that permits multiplexing and requires persistent transport sharing; set the \"multiplex\" client or CurlMultiHandler constructor option to Multiplexing::NONE, or use TransportSharing::PERSISTENT_PREFER.');\n        }\n\n        if (\\defined('CURLOPT_HTTPAUTH')\n            && isset($options['curl'])\n            && \\is_array($options['curl'])\n            && \\array_key_exists((int) \\constant('CURLOPT_HTTPAUTH'), $options['curl'])\n        ) {\n            // Key presence alone conflicts: challenge-response retries are\n            // libcurl-internal follows, which disarm CURLOPT_FRESH_CONNECT\n            // (reuse_fresh && !this_is_a_follow), so the hardening below\n            // cannot cover them.\n            throw new InvalidArgumentException('The \"multiplex\" request option cannot be Multiplexing::NONE combined with the raw CURLOPT_HTTPAUTH cURL option on a CurlMultiHandler that permits multiplexing; remove the raw option, or set the \"multiplex\" client or CurlMultiHandler constructor option to Multiplexing::NONE.');\n        }\n\n        if (Psr7\\Utils::caselessContains($easy->request->getHeaderLine('Expect'), '100-continue')) {\n            // libcurl arms its Expect handling by a caseless substring scan\n            // of the header value (Curl_compareheader), so any value\n            // containing 100-continue can make a 417 response retry as an","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/guzzle/guzzle/blob/9b200fc5805036b331d6031199880dadecae0275/src/Handler/CurlMultiHandler.php#L414-L450","documentation":"Thrown by CurlMultiHandler::applyMultiplexNone() when the per-request multiplex option is NONE on a multiplexing handler, the request is HTTP/1.x, but the handler's transport sharing mode is TransportSharing::PERSISTENT_REQUIRE. Enforcing NONE on older libcurl (without reliable reuse matching) forces a fresh connection, which persistent-require sharing forbids because it disables reuse. The two requirements are incompatible, so it fails closed.","triggerScenarios":"Handler built with transport_sharing => TransportSharing::PERSISTENT_REQUIRE (default multiplexing on); request with multiplex => NONE on libcurl below 7.77.0 (or 8.11.0-8.12.1) where the hardening would force a fresh connection.","commonSituations":"Requiring persistent connection pooling for throughput while trying to isolate a single sensitive transfer; the requirement and the isolation contradict.","solutions":["Switch sharing to TransportSharing::PERSISTENT_PREFER, which does not forbid fresh connections.","Disable multiplexing globally (handler/client multiplex => NONE) so NONE does not need hardening.","Drop the per-request NONE for that transfer."],"exampleFix":"// before\nnew CurlMultiHandler(['transport_sharing' => TransportSharing::PERSISTENT_REQUIRE]);\n$client->get($url, ['multiplex' => Multiplexing::NONE]);\n// after\nnew CurlMultiHandler(['transport_sharing' => TransportSharing::PERSISTENT_PREFER]);\n$client->get($url, ['multiplex' => Multiplexing::NONE]);","handlingStrategy":"validation","validationCode":"use GuzzleHttp\\TransportSharing;\nif (($handlerOptions['transport_sharing'] ?? null) === TransportSharing::PERSISTENT_REQUIRE\n    && ($requestOptions['multiplex'] ?? null) === GuzzleHttp\\Multiplexing::NONE\n) {\n    throw new InvalidArgumentException('PERSISTENT_REQUIRE sharing forbids the fresh-connection hardening that NONE may need');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["PERSISTENT_REQUIRE forbids fresh connections; use PERSISTENT_PREFER if you also need NONE.","Disable multiplexing globally to avoid per-request hardening.","Do not request per-transfer isolation under required persistent pooling."],"tags":["multiplexing","transport-sharing","curl","configuration"],"analyzedSha":"9b200fc5805036b331d6031199880dadecae0275","analyzedAt":"2026-08-04T21:24:26.648Z","schemaVersion":2}