$http = new \GuzzleHttp\Client([
    'proxy' => 'http://proxy.example:8080',
]);

$builder->setHttpClient($http);
$elasticsearch = $builder->build();

$builder is the existing Elastic\Elasticsearch\ClientBuilder with the intended cluster hosts and authentication. Those hosts stay the destinations; the injected HTTP client chooses their intermediary, using an HTTP candidate from the HTTP proxy list when a public route to the cluster is permitted.

With the documented default Guzzle transport, setHttpClientOptions also accepts a proxy option. A different supplied PSR-18 implementation needs its own configuration; Guzzle option names are not an interface shared by every implementation.

setConnectionParams with nested cURL options belongs to an older transport generation. Use the input exposed by the class actually constructed.

Reuse the configured client for its workload. Keep proxy credentials at the intermediary and the API key at Elasticsearch, and preserve a 407 separately from a cluster authorization response.

Artiglyn mynjee