phacility/phabricator · error · Exception

URI "%s" is not a valid fetchable resource. The domain "%s"

Error message

URI "%s" is not a valid fetchable resource. The domain "%s" could not be resolved.

What it means

Fourth gate of requireValidRemoteURIForFetch(): the extracted domain is resolved via PHP's gethostbynamel(). If it returns no addresses (NXDOMAIN, DNS failure, resolver timeout, '.invalid' TLD), Phabricator throws rather than attempting the fetch, because an unresolvable host cannot be safely or usefully retrieved. Resolution happens up-front so the next stage can inspect every resulting IP address.

Source

Thrown at src/infrastructure/env/PhabricatorEnv.php:825

        pht(
          'URI "%s" is not a valid fetchable resource. A valid fetchable '.
          'resource URI must use one of these protocols: %s.',
          $raw_uri,
          implode(', ', array_keys($protocols))));
    }

    $domain = $uri->getDomain();
    if (!strlen($domain)) {
      throw new Exception(
        pht(
          'URI "%s" is not a valid fetchable resource. A valid fetchable '.
          'resource URI must specify a domain.',
          $raw_uri));
    }

    $addresses = gethostbynamel($domain);
    if (!$addresses) {
      throw new Exception(
        pht(
          'URI "%s" is not a valid fetchable resource. The domain "%s" could '.
          'not be resolved.',
          $raw_uri,
          $domain));
    }

    foreach ($addresses as $address) {
      if (self::isBlacklistedOutboundAddress($address)) {
        throw new Exception(
          pht(
            'URI "%s" is not a valid fetchable resource. The domain "%s" '.
            'resolves to the address "%s", which is blacklisted for '.
            'outbound requests.',
            $raw_uri,
            $domain,
            $address));
      }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Verify resolution from the Phabricator host itself: dig +short example.com / getent hosts example.com - fix the typo or the record.
  2. If internal hostnames are involved, configure the web hosts' resolver (or /etc/hosts) so the domain resolves, or use a name that public/internal DNS serves.
  3. For code that fetches optional resources, call isValidRemoteURIForFetch() first and degrade gracefully on unresolvable hosts instead of throwing mid-request.

Example fix

# before
$ host exmaple.com
Host exmaple.com not found: 3(NXDOMAIN)
PhabricatorEnv::requireValidRemoteURIForFetch('https://exmaple.com/a.png', array('https')); // throws

# after: correct the hostname
PhabricatorEnv::requireValidRemoteURIForFetch('https://example.com/a.png', array('https'));
Defensive patterns

Strategy: fallback

Validate before calling

if (@gethostbynamel((new PhutilURI($url))->getDomain()) === false) {
  // DNS cannot resolve this from the Phabricator host; do not attempt the fetch
  return array('err' => 'Domain does not resolve');
}

Try / catch

try {
  PhabricatorEnv::requireValidRemoteURIForFetch($url, array('http', 'https'));
} catch (Exception $ex) {
  // transient DNS failure: retry later with backoff; permanent: report to user
  if (strpos($ex->getMessage(), 'could not be resolved') !== false) {
    throw new PhabricatorWorkerYieldException(60 * 15); // retry in 15 min
  }
  throw $ex;
}

Prevention

When it happens

Trigger: requireValidRemoteURIForFetch() with a typo'd or expired domain ('https://exmaple.com/x'), an internal hostname not resolvable from the Phabricator host's resolver, or transient DNS outage - gethostbynamel('exmaple.com') returns false and the exception includes the failing domain.

Common situations: On-prem installs where web nodes use a resolver that cannot see internal DNS names used in intranet URLs; stale links to decommissioned hosts; DNSSEC or /etc/resolv.conf misconfiguration on the server; test environments with no outbound DNS.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/725ac0bd5d631ca3. Report an issue: GitHub.