phacility/phabricator · error · Exception

URI " " is not a valid linkable resource. A valid linkable…

Error message

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

What it means

The second gate of requireValidRemoteURIForLink(): the URI's protocol must be a key of the `uri.allowed-protocols` config (by default http, https, mailto, and a few others). This whitelist blocks schemes like javascript:, data:, or file: from ever becoming a link Phabricator renders or redirects to. The exception message lists the currently allowed protocols for quick diagnosis.

Solutions

  1. Either change the URI to an allowed scheme (usually https) or extend the whitelist: `./bin/config set uri.allowed-protocols '{"http":true,"https":true,"mailto":true,"ftp":true}'` (set replaces the whole map - merge existing keys).
  2. Audit the failing value: the exception message itself prints the allowed list; compare against the scheme you passed.
  3. Keep the whitelist minimal - each added scheme is a potential phishing/SSRF surface in rendered links.

Example fix

# before
PhabricatorEnv::requireValidRemoteURIForLink('ftp://example.com/pkg.tar.gz');
// throws: ftp not allowed

# after: allow ftp explicitly
$ ./bin/config set uri.allowed-protocols '{"http":true,"https":true,"mailto":true,"ftp":true}'
Defensive patterns

Strategy: validation

Validate before calling

$proto = (new PhutilURI($url))->getProtocol();
$allowed = PhabricatorEnv::getEnvConfig('uri.allowed-protocols');
if (!isset($allowed[$proto])) {
  // either rewrite to https or reject before rendering a link
  $url = PhabricatorURI::convertToHTTPS($url);
}

Try / catch

try {
  PhabricatorEnv::requireValidRemoteURIForLink($url);
} catch (Exception $ex) {
  return id(new PHUITagView())->setName($url)->setType(PHUITagView::TYPE_INVALID);
}

Prevention

When it happens

Trigger: requireValidRemoteURIForLink() receiving a URI whose scheme is outside the whitelist - e.g. 'ftp://example.com/file' when 'ftp' is not configured, or a custom app scheme added by an extension without updating `uri.allowed-protocols`.

Common situations: Linking to ftp://, git://, irc://, or ssh:// resources from remarkup or link fields on installs that never widened the whitelist; disabling protocols centrally for security and having old content fail to render; extensions introducing new schemes.

Related errors


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

Appendix: source

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

   * @param string URI to test.
   * @return void
   * @task uri
   */
  public static function requireValidRemoteURIForLink($raw_uri) {
    $uri = new PhutilURI($raw_uri);

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

    $protocols = self::getEnvConfig('uri.allowed-protocols');
    if (!isset($protocols[$proto])) {
      throw new Exception(
        pht(
          'URI "%s" is not a valid linkable resource. A valid linkable '.
          '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 linkable resource. A valid linkable '.
          'resource URI must specify a domain.',
          $raw_uri));
    }
  }

View on GitHub (pinned to 5720a38cfe)