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 specify a domain.
What it means
Third gate of requireValidRemoteURIForFetch(): the URI must include a non-empty domain (PhutilURI->getDomain()). Schemes with no host component (e.g. 'file:///etc/passwd', 'mailto:x@y' passed to a fetch context, or 'https:///path') pass protocol checks but give nothing to resolve, and host-less fetches are exactly the shape of filesystem/SSRF abuse, so they are rejected outright.
Source
Thrown at src/infrastructure/env/PhabricatorEnv.php:816
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) {
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)) {View on GitHub (pinned to 5720a38cfe)
Solutions
- Supply a fully-qualified remote URI: 'https://example.com/resource'.
- If you meant a local file, this API is the wrong tool - local assets must be handled by dedicated import mechanisms, not remote fetch.
- Reject host-less URIs at the form/import boundary so users never store them.
Example fix
// before
PhabricatorEnv::requireValidRemoteURIForFetch('https:///img/logo.png', array('https'));
// throws: no domain
// after
PhabricatorEnv::requireValidRemoteURIForFetch('https://cdn.example.com/img/logo.png', array('https')); Defensive patterns
Strategy: validation
Validate before calling
$uri = new PhutilURI($url);
if (!strlen($uri->getDomain())) {
throw new Exception('Refusing to fetch host-less URI: '.$url);
} Type guard
function uriHasHost($raw) {
$uri = new PhutilURI($raw);
return strlen($uri->getProtocol()) && strlen($uri->getDomain());
} Try / catch
try {
PhabricatorEnv::requireValidRemoteURIForFetch($url, array('http', 'https'));
} catch (Exception $ex) {
// host-less URIs are never fetchable; degrade to a placeholder resource
return $default_image;
} Prevention
- Reject file:// and host-less URIs in form validation - they are always a mistake or an attack.
- Build URLs from components (scheme, host, path) rather than string concatenation.
- Treat 'missing host' as a data-quality defect: clean it at import time.
When it happens
Trigger: requireValidRemoteURIForFetch() receiving 'file:///srv/secret' (file is not in allowed protocols normally, but any allowed scheme with empty host hits this branch), 'https:///resource', or a URI where the host was lost in templating.
Common situations: Attempts (accidental or hostile) to make Phabricator fetch local file:// resources; URL-building bugs that drop the host; imported data with truncated URLs; penetration tests probing the fetch validator.
Related errors
- URI "%s" is not a valid fetchable resource. A valid fetchabl
- URI "%s" is not a valid fetchable resource. A valid fetchabl
- URI "%s" is not a valid fetchable resource. The domain "%s"
- URI "%s" is not a valid linkable resource. A valid linkable
- URI "%s" is not a valid fetchable resource. The domain "%s"
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/bbeba78b7346a698.
Report an issue: GitHub.