composer/composer · error · RuntimeException

unable to find proxy host in {envName}

Error message

unable to find proxy host in {envName}

What it means

Thrown by ProxyItem when parse_url() succeeded but returned no 'host' component — the proxy URL has a scheme/port but no reachable host. Composer needs a host to build the curl CONNECT target, so it refuses the configuration. The message names the offending env var.

Source

Thrown at src/Composer/Util/Http/ProxyItem.php:48

    private $optionsAuth;

    /**
     * @param string $proxyUrl The value from the environment
     * @param string $envName The name of the environment variable
     * @throws \RuntimeException If the proxy url is invalid
     */
    public function __construct(string $proxyUrl, string $envName)
    {
        $syntaxError = sprintf('unsupported `%s` syntax', $envName);

        if (strpbrk($proxyUrl, "\r\n\t") !== false) {
            throw new \RuntimeException($syntaxError);
        }
        if (false === ($proxy = parse_url($proxyUrl))) {
            throw new \RuntimeException($syntaxError);
        }
        if (!isset($proxy['host'])) {
            throw new \RuntimeException('unable to find proxy host in ' . $envName);
        }

        $scheme = isset($proxy['scheme']) ? strtolower($proxy['scheme']) . '://' : 'http://';
        $safe = '';

        if (isset($proxy['user'])) {
            $safe = '***';
            $user = $proxy['user'];
            $auth = rawurldecode($proxy['user']);

            if (isset($proxy['pass'])) {
                $safe .= ':***';
                $user .= ':' . $proxy['pass'];
                $auth .= ':' . rawurldecode($proxy['pass']);
            }

            $safe .= '@';

View on GitHub (pinned to 6ffc117740)

Solutions

  1. Re-export the env var including the host: `export HTTP_PROXY=http://proxy.example.com:8080`.
  2. If the host lives in a separate variable, ensure it is set before composing the URL.
  3. Validate with `php -r 'var_dump(parse_url(getenv("HTTP_PROXY"), PHP_URL_HOST));'`.
  4. Unset the variable if no proxy is intended.

Example fix

// before
export HTTP_PROXY="http://:8080"
// after
export HTTP_PROXY="http://proxy.example.com:8080"
Defensive patterns

Strategy: validation

Validate before calling

function assertProxyHost(string $url, string $envName): void {
    $p = parse_url($url);
    if ($p === false || empty($p['host'])) {
        throw new \InvalidArgumentException($envName.' missing proxy host');
    }
}

Type guard

function proxyHasHost(string $v): bool { $p = parse_url($v); return $p !== false && !empty($p['host']); }

Try / catch

try { new \Composer\Util\Http\ProxyItem($url, $envName); } catch (\RuntimeException $e) {
    if (str_starts_with($e->getMessage(), 'unable to find proxy host')) {
        throw new \RuntimeException('Re-export '.$envName.' as http://HOST:PORT', 0, $e);
    }
    throw $e;
}

Prevention

When it happens

Trigger: Values like `http://:8080`, `https://`, or a bare port `8080` where parse_url treats the segment as path/port rather than host. Triggered when Composer first constructs the ProxyItem from the environment.

Common situations: Forgotten hostname in templated CI config, partially overwritten env var, or a value constructed by concatenating only scheme+port. Common when the hostname comes from a separate variable that was never set.

Related errors


AI-assisted analysis of composer/composer@6ffc117740 (2026-08-07). Data as JSON: /api/errors/c69cf13baf4abb3b. Report an issue: GitHub.