symfony/http-foundation · error · RuntimeException

Unable to check Ipv6. Check that PHP was not compiled with…

Error message

Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".

What it means

IpUtils::checkIp6() needs IPv6 support to compare addresses (it ultimately relies on inet_pton / the sockets extension). If PHP was compiled with --disable-ipv6 (no AF_INET6 constant, no sockets extension, and inet_pton('::1') fails), the method cannot do its job and throws this RuntimeException instead of returning a wrong result. This is an environment-capability check, not a data validation error.

Solutions

  1. Recompile PHP with IPv6 support (drop the --disable-ipv6 configure option).
  2. Enable/install the sockets extension (install php-sockets / compile with --enable-sockets) so AF_INET6 is defined.
  3. Switch to an official PHP Docker image or distro package that includes IPv6 support.
  4. Guard calls: only call checkIp6() when the request IP is IPv4, or check extension_loaded('sockets') && defined('AF_INET6') first and fail gracefully.
  5. Upgrade to a PHP build where inet_pton supports IPv6 (verify with var_dump(@inet_pton('::1'))).

Example fix

// before
$allowed = IpUtils::checkIp($requestIp, '2001:db8::/32'); // RuntimeException on crippled PHP

// after
if (filter_var($requestIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)
    && !\extension_loaded('sockets') && !@inet_pton('::1')) {
    throw new \RuntimeException('IPv6 support missing; rebuild PHP with IPv6 enabled.');
}
$allowed = IpUtils::checkIp($requestIp, '2001:db8::/32');
Defensive patterns

Strategy: fallback

Validate before calling

// before relying on IPv6 checks
$ipv6Supported = (\extension_loaded('sockets') && \defined('AF_INET6')) || @inet_pton('::1') !== false;
if (!$ipv6Supported) {
    // skip IPv6 rules, use IPv4-only handling, or fail fast with a clear setup error
}

Type guard

function phpSupportsIpv6(): bool {
    return (\extension_loaded('sockets') && \defined('AF_INET6')) || @inet_pton('::1') !== false;
}

Try / catch

try {
    $ok = IpUtils::checkIp($requestIp, $allowedIps);
} catch (\RuntimeException $e) {
    $logger->error('PHP lacks IPv6 support', ['exception' => $e]);
    $ok = false; // deny or fall back to IPv4-only matching
}

Prevention

When it happens

Trigger: Calling checkIp6() or checkIp() with an IPv6 address on a PHP build compiled with --disable-ipv6; running in a minimal Docker/alpine PHP image or a custom-compiled PHP without the sockets extension and without working inet_pton.

Common situations: Self-hosted PHP compiled without IPv6; hardened/minimal container images; CI runners with a stripped-down PHP; Symfony access-control rules (security.yaml access_control with IP ranges) evaluated on such a runtime.

Related errors


AI-assisted analysis of symfony/http-foundation@5aea19cd67 (2026-09-13). Data as JSON: /api/errors/10961c37ddd95e82. Report an issue: GitHub.

Appendix: source

Thrown at IpUtils.php:147

     * In case a subnet is given, it checks if it contains the request IP.
     *
     * @author David Soria Parra <dsp at php dot net>
     *
     * @see https://github.com/dsp/v6tools
     *
     * @param string $ip IPv6 address or subnet in CIDR notation
     *
     * @throws \RuntimeException When IPV6 support is not enabled
     */
    public static function checkIp6(string $requestIp, string $ip): bool
    {
        $cacheKey = $requestIp.'-'.$ip.'-v6';
        if (null !== $cacheValue = self::getCacheResult($cacheKey)) {
            return $cacheValue;
        }

        if (!((\extension_loaded('sockets') && \defined('AF_INET6')) || @inet_pton('::1'))) {
            throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
        }

        // Check to see if we were given a IP4 $requestIp or $ip by mistake
        if (!filter_var($requestIp, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
            return self::setCacheResult($cacheKey, false);
        }

        if (str_contains($ip, '/')) {
            [$address, $netmask] = explode('/', $ip, 2);

            if (!filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
                return self::setCacheResult($cacheKey, false);
            }

            if ('0' === $netmask) {
                return (bool) unpack('n*', @inet_pton($address));
            }

View on GitHub (pinned to 5aea19cd67)