{"id":"2914202916a58396","repo":"guzzle/guzzle","slug":"the-stream-handler-cannot-guarantee-a-multiplexed","errorCode":null,"errorMessage":"The stream handler cannot guarantee a multiplexed protocol; required multiplexing needs a cURL handler.","messagePattern":"The stream handler cannot guarantee a multiplexed protocol; required multiplexing needs a cURL handler\\.","errorType":"exception","errorClass":"GuzzleHttp\\Exception\\RequestException","httpStatus":null,"severity":"error","filePath":"src/Handler/StreamHandler.php","lineNumber":174,"sourceCode":"\n        // Sleep if there is a delay specified.\n        if (isset($options['delay'])) {\n            \\usleep((int) ($options['delay'] * 1000));\n        }\n\n        $multiplex = $options['multiplex'] ?? null;\n\n        // Multiplexing::NONE is trivially satisfied: the stream handler sends\n        // one HTTP/1.x request per connection and never multiplexes.\n        if (null !== $multiplex && !\\in_array($multiplex, [Multiplexing::NONE, Multiplexing::EAGER, Multiplexing::WAIT, Multiplexing::REQUIRE_EAGER, Multiplexing::REQUIRE_WAIT], true)) {\n            throw new InvalidArgumentException(\\sprintf(\n                'The \"multiplex\" option must be null or a GuzzleHttp\\\\Multiplexing::* constant; received %s.',\n                \\get_debug_type($multiplex)\n            ));\n        }\n\n        if (\\in_array($multiplex, [Multiplexing::REQUIRE_EAGER, Multiplexing::REQUIRE_WAIT], true)) {\n            throw new RequestException('The stream handler cannot guarantee a multiplexed protocol; required multiplexing needs a cURL handler.', $request);\n        }\n\n        $protocolVersion = $request->getProtocolVersion();\n\n        if ('' === $protocolVersion) {\n            throw new RequestException('HTTP protocol version must not be empty.', $request);\n        }\n\n        if (1 !== \\preg_match('/^\\d+(?:\\.\\d+)?$/D', $protocolVersion)) {\n            throw new RequestException('HTTP protocol version must be a valid HTTP version number.', $request);\n        }\n\n        if ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {\n            throw new RequestException(sprintf('HTTP/%s is not supported by the stream handler.', $protocolVersion), $request);\n        }\n\n        if (isset($options['on_stats']) && !\\is_callable($options['on_stats'])) {\n            throw new InvalidArgumentException('on_stats must be callable');","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/guzzle/guzzle/blob/9b200fc5805036b331d6031199880dadecae0275/src/Handler/StreamHandler.php#L156-L192","documentation":"Thrown by StreamHandler::__invoke when the 'multiplex' option is Multiplexing::REQUIRE_EAGER or REQUIRE_WAIT. The stream handler speaks only HTTP/1.x (one request per connection) and can never provide a multiplexed protocol, so a hard requirement for multiplexing cannot be satisfied and is rejected before any I/O rather than silently degrading.","triggerScenarios":"Configuring the client/handler with a StreamHandler (or falling back to it) while a request sets 'multiplex' => Multiplexing::REQUIRE_EAGER or REQUIRE_WAIT to demand an HTTP/2 connection.","commonSituations":"Defaulting to StreamHandler on systems without the cURL extension; building a handler stack that prefers cURL but falls back to StreamHandler while requests demand multiplexing; misreading REQUIRE_* semantics.","solutions":["Use a cURL-based handler (CurlMultiHandler) which supports HTTP/2 multiplexing for REQUIRE_EAGER/REQUIRE_WAIT.","Downgrade the requirement to Multiplexing::EAGER or WAIT if multiplexing is preferred but not mandatory.","Ensure the ext-curl extension is installed so the default handler is cURL, not the stream handler."],"exampleFix":"// before\n$handler = new StreamHandler();\n$client->request('GET', $url, ['multiplex' => Multiplexing::REQUIRE_EAGER]);\n// after\n$handler = HandlerStack::create(); // uses CurlMultiHandler when ext-curl is present\n$client->request('GET', $url, ['multiplex' => Multiplexing::REQUIRE_EAGER]);","handlingStrategy":"fallback","validationCode":"// Choose the handler based on whether multiplexing is required.\n$needMultiplex = in_array($reqOptions['multiplex'] ?? null, [Multiplexing::REQUIRE_EAGER, Multiplexing::REQUIRE_WAIT], true);\n$handler = $needMultiplex && function_exists('curl_init')\n    ? new CurlMultiHandler()\n    : new StreamHandler();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure ext-curl is installed so the default handler supports HTTP/2 multiplexing.","Do not REQUIRE multiplexing unless your handler stack is cURL-based.","Use EAGER/WAIT (preference) instead of REQUIRE_* unless multiplexing is mandatory."],"tags":["stream-handler","multiplexing","http2","handler-selection"],"analyzedSha":"9b200fc5805036b331d6031199880dadecae0275","analyzedAt":"2026-08-04T21:24:26.648Z","schemaVersion":2}