guzzle/guzzle · error · \InvalidArgumentException
The "multiplex" request option cannot be Multiplexing::NONE…
Error message
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.
What it means
Required persistent sharing forbids `CURLOPT_FRESH_CONNECT` because it kills connection reuse, but `Multiplexing::NONE` on a multiplexing handler may need to force a fresh connection to harden the sole-use guarantee on certain libcurl versions. To keep the guarantee version-independent, Guzzle rejects the combination outright.
Solutions
- Disable multiplexing globally via the `multiplex` client/handler option (`Multiplexing::NONE`), which makes NONE hold without forcing fresh connections.
- Switch required sharing to `TransportSharing::PERSISTENT_PREFER`.
- Drop the per-request `Multiplexing::NONE`.
Example fix
// before
new CurlMultiHandler(['transport_sharing' => TransportSharing::PERSISTENT_REQUIRE]);
$client->get($url, ['multiplex' => Multiplexing::NONE]);
// after
new CurlMultiHandler([
'transport_sharing' => TransportSharing::PERSISTENT_REQUIRE,
'multiplex' => Multiplexing::NONE,
]); Defensive patterns
Strategy: validation
Validate before calling
$persistReq = ($hOpts['transport_sharing'] ?? null) === TransportSharing::PERSISTENT_REQUIRE;
$handlerPermitsMultiplex = ($hOpts['multiplex'] ?? null) !== Multiplexing::NONE;
if ($persistReq && $handlerPermitsMultiplex
&& ($reqOpts['multiplex'] ?? null) === Multiplexing::NONE
) {
throw new \LogicException('PERSISTENT_REQUIRE sharing conflicts with per-request Multiplexing::NONE');
} Prevention
- PERSISTENT_REQUIRE and per-request sole-use are incompatible; pick one strategy.
- If sole-use matters, disable multiplexing at the handler level rather than per request.
When it happens
Trigger: Handler configured with `transport_sharing => TransportSharing::PERSISTENT_REQUIRE`, request with `'multiplex' => Multiplexing::NONE` over HTTP/1.x on a handler that permits multiplexing. Guarded at line 426.
Common situations: Requiring cross-handler connection reuse for performance while still marking specific sensitive requests as sole-use.
Related errors
- A cURL share handle cannot be provided when transport…
- A cURL share handle is required when transport sharing is…
- cannot be combined with persistent transport sharing…
- The cURL share handle state mode does not match the…
- The "max_host_connections" and "max_total_connections"…
AI-assisted analysis of guzzle/guzzle@d1cbca7697 (2026-08-06).
Data as JSON: /api/errors/38e1812b62b89daa.
Report an issue: GitHub.
Appendix: source
Thrown at src/Handler/CurlMultiHandler.php:432
return;
}
if (!$this->ownsFactory) {
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.');
}
$version = $easy->request->getProtocolVersion();
if ('1.0' !== $version && '1.1' !== $version) {
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".');
}
if (null !== $this->shareHandleState && TransportSharing::PERSISTENT_REQUIRE === $this->shareHandleState->mode) {
// The matcher-window hardening below may force a fresh
// connection, which required persistent sharing forbids because
// it disables connection reuse (CurlFactory applies the same
// rule to the raw option); rejected on every runtime so
// acceptance stays version-independent.
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.');
}
if (\defined('CURLOPT_HTTPAUTH')
&& isset($options['curl'])
&& \is_array($options['curl'])
&& \array_key_exists((int) \constant('CURLOPT_HTTPAUTH'), $options['curl'])
) {
// Key presence alone conflicts: challenge-response retries are
// libcurl-internal follows, which disarm CURLOPT_FRESH_CONNECT
// (reuse_fresh && !this_is_a_follow), so the hardening below
// cannot cover them.
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.');
}
if (Psr7\Utils::caselessContains($easy->request->getHeaderLine('Expect'), '100-continue')) {
// libcurl arms its Expect handling by a caseless substring scan
// of the header value (Curl_compareheader), so any value
// containing 100-continue can make a 417 response retry as anView on GitHub (pinned to d1cbca7697)