Problem/Motivation

Since Guzzle 7.11.0, all Varnish purge/ban requests fail when general.varnish_server is configured as a bare
host without a URL scheme (e.g. varnish instead of http://varnish) — a very common setup (Docker service name, internal hostname).

CacheManager::sendRequest() builds the request URL by simple concatenation:

// src/CacheManager.php
  foreach (explode(' ', $servers) as $server) {
    $uri = $server . $path;            // "varnish" . "/tags" => "varnish/tags"
    $result = $result && $this->singleRequest($uri, $options);
  }
  

With varnish_server = varnish, $uri becomes the schemeless string varnish/tags. Guzzle 7.11.0 added
the protocols request option (default ['http', 'https']), which now rejects schemeless URLs:

Added the protocols request option to restrict allowed URI schemes for request transfers

Guzzle CHANGELOG 7.11.0 (2026-06-02)

The resulting exception is caught and logged by singleRequest(), so the purge silently does nothing while flooding
the log on every cache-tag invalidation:

GuzzleHttp\Exception\RequestException: The scheme "" is not allowed by the
  protocols request option
  in vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php

Drupal core ≥ 10.6.12 pulls Guzzle 7.12.x, so any site upgrading core hits this. Confirmed on adv_varnish 4.0.14 and 4.0.15.

Steps to reproduce

  1. Drupal core ≥ 10.6.12 (Guzzle ≥ 7.11).
  2. Set general.varnish_server to a bare host, e.g. varnish.
  3. Run drush cr (or save any entity).
  4. Result: RequestException: The scheme "" is not allowed by the protocols request option is logged, and Varnish is never
    purged.

Proposed resolution

Normalize the server to a valid URL in sendRequest(): default to http:// when no scheme is present, leaving
http:///https:// values untouched (backward compatible). Also skip empty entries.

foreach (explode(' ', $servers) as $server) {                  
    $server = trim($server);
    if ($server === '') {
      continue;
    }
    if (!str_contains($server, '://')) {
      $server = 'http://' . $server;
    }
    $uri = $server . $path;
    $result = $result && $this->singleRequest($uri, $options);
  }
  

Remaining tasks

Create a MR.

Data model changes

n/a

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

  • 4.x Comparechanges, plain diff MR !45

Comments

tostinni created an issue. See original summary.

tostinni’s picture

Status: Active » Needs review

MR created

eelkeblok’s picture

Status: Needs review » Reviewed & tested by the community

Noticed this after recent updates, looks like a simple solution.

shumer’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.