phacility/phabricator · error · Exception
Request to "%s" failed: %s
Error message
Request to "%s" failed: %s
What it means
Thrown by PhabricatorFileImageProxyController::getExternalResponse() when a cached PhabricatorFileExternalRequest reports an unsuccessful server-side fetch. Phabricator's image proxy downloads remote images on the server (so user browsers never contact the remote host directly) and caches the outcome; this exception re-surfaces the original transport or HTTP error for the proxied URI. The message embeds the requested URI and the cached response message (cURL error or HTTP status text).
Source
Thrown at src/applications/files/controller/PhabricatorFileImageProxyController.php:122
throw new Exception(
pht(
'Hit duplicate key collision when saving proxied image, but '.
'failed to load duplicate row (for URI "%s").',
$img_uri));
}
}
}
unset($unguarded);
return $this->getExternalResponse($external_request);
}
private function getExternalResponse(
PhabricatorFileExternalRequest $request) {
if (!$request->getIsSuccessful()) {
throw new Exception(
pht(
'Request to "%s" failed: %s',
$request->getURI(),
$request->getResponseMessage()));
}
$file = id(new PhabricatorFileQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs(array($request->getFilePHID()))
->executeOne();
if (!$file) {
throw new Exception(
pht(
'The underlying file does not exist, but the cached request was '.
'successful. This likely means the file record was manually '.
'deleted by an administrator.'));
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- From the web host, verify the URI is fetchable: curl -I '<image URL>'; fix or remove the dead hotlink
- Check outbound network/proxy configuration so the Phabricator server can reach the image host (ports 80/443, DNS, TLS trust)
- Delete the cached failed row in file_externalrequest for that URI so the proxy retries instead of replaying the cached error
- If egress is restricted, whitelist the image host or disable the image-proxy feature
Example fix
// before
$response = $this->getExternalResponse($external_request);
return $response;
// after
try {
return $this->getExternalResponse($external_request);
} catch (Exception $ex) {
// URI and transport error are in $ex->getMessage(); degrade gracefully
return id(new AphrontAjaxResponse())
->setContent(array('imageURI' => $default_image_uri));
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!$external_request->getIsSuccessful()) {
// cached outcome is a failure: do not call getExternalResponse()
return $default_image_response;
} Try / catch
try { $response = $this->getExternalResponse($external_request); } catch (Exception $ex) { log $ex->getMessage() (it contains the URI and transport error) and degrade to a default image instead of an uncaught 500. } Prevention
- Validate remote image URLs at embed time and drop dead hotlinks early
- Keep outbound network/proxy egress from the web host healthy and monitored
- Treat cached proxy failures as short-lived: clear file_externalrequest rows for a URI after fixing the remote host
When it happens
Trigger: Loading content that embeds a remote image whose proxied fetch failed: the remote host returned 404/403/500, DNS resolution failed, the connection timed out, or SSL verification failed. Also triggered when a previously cached failure row in file_externalrequest is replayed before its TTL expires.
Common situations: Hotlinked images that were later removed or now require auth; egress firewalls blocking the Phabricator web host; expired TLS certificates on the image host; slow image hosts exceeding the fetch timeout; a stale cache row replaying a transient outage.
Related errors
- The underlying file does not exist, but the cached request w
- Unable to connect to memcache server (%s:%d)!
- Specify either "--all" or "--caches", not both.
- Select caches to purge with "--all" or "--caches". Available
- Cache purger "%s" is not recognized. Available caches are: %
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/92dfe126281a9389.
Report an issue: GitHub.