getgrav/grav · error · InvalidArgumentException

Uri host name validation failed

Error message

Uri host name validation failed

What it means

After the is_string check, filterHost() validates the value: a bare IPv6 address gets bracketed, but any other non-empty host must match HOSTNAME_REGEX (labels of alphanumerics/hyphens joined by dots) or InvalidArgumentException 'Uri host name validation failed' is thrown. Notably the regex rejects underscores, empty labels (double dots, leading/trailing dot), and labels starting/ending with a hyphen. IPv4 passes because numeric labels satisfy the pattern.

Source

Thrown at system/src/Grav/Framework/Uri/UriPartsFilter.php:72

            $info
        ) ?? '';
    }

    /**
     * @param string $host
     * @return string
     * @throws InvalidArgumentException If the host is invalid.
     */
    public static function filterHost($host)
    {
        if (!is_string($host)) {
            throw new InvalidArgumentException('Uri host must be a string');
        }

        if (filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
            $host = '[' . $host . ']';
        } elseif ($host && preg_match(static::HOSTNAME_REGEX, $host) !== 1) {
            throw new InvalidArgumentException('Uri host name validation failed');
        }

        return strtolower($host);
    }

    /**
     * Filter Uri port.
     *
     * This method
     *
     * @param int|null $port
     * @return int|null
     * @throws InvalidArgumentException If the port is invalid.
     */
    public static function filterPort($port = null)
    {
        if (null === $port || (is_int($port) && ($port >= 0 && $port <= 65535))) {
            return $port;

View on GitHub (pinned to 6040efed04)

Solutions

  1. Replace underscores with hyphens in the hostname (underscores are invalid in RFC hostnames)
  2. Split off the port before filtering: `[$host, $port] = explode(':', $host . ':')` and pass the port to withPort()
  3. Strip a trailing dot and re-check labels if you accept FQDNs from DNS output
  4. Validate/sanitize Host-derived input from headers before building Uris

Example fix

// before
$uri = $uri->withHost('my_site.local:8080'); // underscore + port -> validation failed

// after
$host = str_replace('_', '-', 'my_site.local');
$uri = $uri->withHost($host)->withPort(8080);
Defensive patterns

Strategy: validation

Validate before calling

function isAcceptableHost(string $host): bool
{
    $host = rtrim($host, '.'); // tolerate FQDN trailing dot
    return $host === ''
        || (bool) filter_var($host, FILTER_VALIDATE_IP)
        || preg_match('/^(?=.{1,253}$)([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)*[a-z0-9]([a-z0-9-]*[a-z0-9])?$/i', $host) === 1;
}

Try / catch

try {
    $uri = $uri->withHost($host);
} catch (\InvalidArgumentException $e) {
    // 'Uri host name validation failed' — sanitize or reject the host
    $uri = $uri->withHost('localhost'); // or throw 400 for user-supplied hosts
}

Prevention

When it happens

Trigger: Hostnames containing underscores (`my_site.local`, Docker aliases like `my_app_1`); a host with a trailing dot (`example.com.`); passing `host:port` together so the colon fails the regex; labels with leading/trailing hyphens; hosts built from unvalidated header input containing spaces or slashes.

Common situations: Internal/dev hostnames with underscores (technically invalid per RFC but common in DNS and Docker); misconfigured SERVER_NAME/HTTP_HOST; proxies forwarding a malformed Host header; code passing an unsplit 'example.com:8080' into withHost().

Related errors


AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17). Data as JSON: /api/errors/4632641822dc8047. Report an issue: GitHub.