{"record":{"id":"503da09f26bfc5b0","repo":"phacility/phabricator","slug":"uri-s-is-not-a-valid-linkable-resource-a-valid-503da0","errorCode":null,"errorMessage":"URI \"%s\" is not a valid linkable resource. A valid linkable resource URI must use one of these protocols: %s.","messagePattern":"URI \"(.+?)\" is not a valid linkable resource\\. A valid linkable resource URI must use one of these protocols: (.+?)\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/infrastructure/env/PhabricatorEnv.php","lineNumber":739,"sourceCode":"   * @param string URI to test.\n   * @return void\n   * @task uri\n   */\n  public static function requireValidRemoteURIForLink($raw_uri) {\n    $uri = new PhutilURI($raw_uri);\n\n    $proto = $uri->getProtocol();\n    if (!strlen($proto)) {\n      throw new Exception(\n        pht(\n          'URI \"%s\" is not a valid linkable resource. A valid linkable '.\n          'resource URI must specify a protocol.',\n          $raw_uri));\n    }\n\n    $protocols = self::getEnvConfig('uri.allowed-protocols');\n    if (!isset($protocols[$proto])) {\n      throw new Exception(\n        pht(\n          'URI \"%s\" is not a valid linkable resource. A valid linkable '.\n          'resource URI must use one of these protocols: %s.',\n          $raw_uri,\n          implode(', ', array_keys($protocols))));\n    }\n\n    $domain = $uri->getDomain();\n    if (!strlen($domain)) {\n      throw new Exception(\n        pht(\n          'URI \"%s\" is not a valid linkable resource. A valid linkable '.\n          'resource URI must specify a domain.',\n          $raw_uri));\n    }\n  }\n\n","sourceCodeStart":721,"sourceCodeEnd":757,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/env/PhabricatorEnv.php#L721-L757","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["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).","Audit the failing value: the exception message itself prints the allowed list; compare against the scheme you passed.","Keep the whitelist minimal - each added scheme is a potential phishing/SSRF surface in rendered links."],"exampleFix":"# before\nPhabricatorEnv::requireValidRemoteURIForLink('ftp://example.com/pkg.tar.gz');\n// throws: ftp not allowed\n\n# after: allow ftp explicitly\n$ ./bin/config set uri.allowed-protocols '{\"http\":true,\"https\":true,\"mailto\":true,\"ftp\":true}'","handlingStrategy":"validation","validationCode":"$proto = (new PhutilURI($url))->getProtocol();\n$allowed = PhabricatorEnv::getEnvConfig('uri.allowed-protocols');\nif (!isset($allowed[$proto])) {\n  // either rewrite to https or reject before rendering a link\n  $url = PhabricatorURI::convertToHTTPS($url);\n}","typeGuard":null,"tryCatchPattern":"try {\n  PhabricatorEnv::requireValidRemoteURIForLink($url);\n} catch (Exception $ex) {\n  return id(new PHUITagView())->setName($url)->setType(PHUITagView::TYPE_INVALID);\n}","preventionTips":["Keep uri.allowed-protocols minimal; add schemes only with a security review.","Normalize stored links to https during imports so old ftp/git URLs do not resurface.","When disabling protocols centrally, expect legacy content to render as invalid tags, not crash."],"tags":["phabricator","uri","protocol-whitelist","config","security"],"backgroundTag":"uri-protocol-not-allowed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}