phacility/phabricator · error · Exception

URI "%s" is not a valid fetchable resource. A valid fetchabl

Error message

URI "%s" is not a valid fetchable resource. A valid fetchable resource URI must use one of these protocols: %s.

What it means

Second gate of requireValidRemoteURIForFetch(): the URI's protocol must be in the caller-provided protocol list (array_fuse turns it into a lookup map). Even syntactically valid schemes like 'ftp://' or 'file://' are refused because the fetching code path only speaks the protocols it declared. The message prints the accepted list to make the mismatch obvious.

Source

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

   */
  public static function requireValidRemoteURIForFetch(
    $raw_uri,
    array $protocols) {

    $uri = new PhutilURI($raw_uri);

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

    $protocols = array_fuse($protocols);
    if (!isset($protocols[$proto])) {
      throw new Exception(
        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) {

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Change the URI to a scheme the call site allows (usually https).
  2. If the scheme is legitimately fetchable, widen the caller's protocol argument - this is per-call-site in code, not config - after confirming the downstream HTTP client actually supports it.
  3. Normalize stored http:// URLs to https:// when the destination supports TLS rather than widening the whitelist.

Example fix

// before: call site allows https only
PhabricatorEnv::requireValidRemoteURIForFetch('http://cdn.example.com/a.png', array('https'));
// throws

// after: upgrade the target or widen deliberately
PhabricatorEnv::requireValidRemoteURIForFetch('https://cdn.example.com/a.png', array('https'));
Defensive patterns

Strategy: validation

Validate before calling

$proto = (new PhutilURI($url))->getProtocol();
if (!in_array($proto, array('http', 'https'), true)) {
  // reject or upgrade before the fetch validator throws
  $url = preg_replace('#^http:#', 'https:', $url);
}

Try / catch

try {
  PhabricatorEnv::requireValidRemoteURIForFetch($url, $allowed);
} catch (Exception $ex) {
  return array('err' => $ex->getMessage()); // graceful per-item failure in bulk imports
}

Prevention

When it happens

Trigger: requireValidRemoteURIForFetch($uri, array('https')) called with 'http://example.com/x' (http not in list), or repository/image URLs using git://, ftp://, or file:// schemes where only http/https are allowed by the call site.

Common situations: Hardening a call site from array('http','https') down to https-only and older stored http:// URLs now failing; users pasting ftp:// or file:// links into fields that trigger server-side fetching; custom fetchers forgetting to include their scheme in the allowed list.

Related errors


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