BookStackApp/BookStack · error · HttpFetchException
errors.http_ssr_url_no_match
Error message
errors.http_ssr_url_no_match
What it means
SsrUrlValidator::ensureAllowed() throws HttpFetchException with errors.http_ssr_url_no_match when the supplied URL does not match any configured allowed SSR host pattern. BookStack validates outbound URLs (used for fetching remote resources such as avatars) against the 'allow' host list to prevent SSRF attacks to internal networks.
Source
Thrown at app/Util/SsrUrlValidator.php:31
* protocol and host. It can optionally define a path prefix as part of the URL.
* Wildcards, via a '*', can be used within these elements to match anything but a '/'.
*/
class SsrUrlValidator
{
protected string $config;
public function __construct(?string $config = null)
{
$this->config = $config ?? config('app.ssr_hosts') ?? '';
}
/**
* @throws HttpFetchException
*/
public function ensureAllowed(string $url): void
{
if (!$this->allowed($url)) {
throw new HttpFetchException(trans('errors.http_ssr_url_no_match'));
}
}
/**
* Check if the given URL is allowed by the configured SSR host values.
*/
public function allowed(string $url): bool
{
$allowed = $this->getHostPatterns();
foreach ($allowed as $pattern) {
if ($this->urlMatchesPattern($url, $pattern)) {
return true;
}
}
return false;
}View on GitHub (pinned to 18f8469a1c)
Solutions
- Add the URL's host to the SSR allowed hosts configuration (e.g. via the allow-list settings/REGEX host patterns)
- Verify allowed($url) matching logic: scheme, case, port and wildcards in your patterns
- Catch HttpFetchException and surface the SSR-block message; do not retry the same URL
- Audit requested URLs for redirects that land on non-allowed hosts
Example fix
// before
(new SsrUrlValidator())->ensureAllowed('https://internal.example.com/avatar.png');
// after
// config: allowed hosts includes 'internal.example.com'
(new SsrUrlValidator())->ensureAllowed('https://internal.example.com/avatar.png'); Defensive patterns
Strategy: validation
Validate before calling
// Validate the URL host against your allowed SSR hosts before fetching
$parsed = parse_url($url, PHP_URL_HOST);
$allowed = ['example.com', 'cdn.example.com']; // mirror your configured SSR allowlist
if (!in_array(strtolower((string) $parsed), $allowed, true)) {
throw new \InvalidArgumentException("Host not allowed for SSR fetch: {$parsed}");
} Try / catch
try {
(new \BookStack\Util\SsrUrlValidator())->ensureAllowed($url);
} catch (\BookStack\Exceptions\HttpFetchException $e) {
abort(400, 'URL blocked by SSRF protection');
} Prevention
- Keep the SSR allowed-hosts config in sync across environments
- Include all CDN/avatar hosts in the allowlist
- Avoid fetching user-supplied URLs pointing at internal IPs
- Log blocked URLs to spot legitimate hosts missing from the allowlist
When it happens
Trigger: Any code path calling ensureAllowed($url) (avatar/image fetch flows) where $url's host fails the allowed($url) check against configured allowed hosts — e.g. hosts not whitelisted, or misparsed host values.
Common situations: Empty or overly narrow APP/SSR allowed-hosts configuration; hosts with different scheme/port/case not matching patterns; internal IPs (10.x, 169.254.x, localhost) blocked by default SSRF guards; environment migrations where the allowlist wasn't updated.
Related errors
- Failed to read signing key with error:
- Token signature could not be validated using the provided ke
- Missing or non-matching token issuer value
- Invalid SP metadata:
- errors.page_custom_home_deletion
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/74b58cf97b191358.
Report an issue: GitHub.