epi052/feroxbuster · warning
prevented request to
Error message
prevented request to {} due to {:?} || {:?} What it means
request_link checks the target URL against the configured denylists before making a request; if should_deny_url matches (by URL pattern or regex), the request is refused with this error naming the URL and both denylist contents. It prevents the link extractor from fetching URLs the user excluded.
Solutions
- Review and narrow the url_denylist/regex_denylist values shown in the error message so intended links are not matched
- Anchor regex denylist patterns (e.g. '^https://host/admin/') instead of broad substrings
- If the URL should be scanned, remove it from the denylist or use a more specific entry
- Accept the error as expected behavior if the denial is intentional; skip/ignore those links
Example fix
// before regex_denylist: [".*admin.*"] // matches crawled links like /admin-blog // after regex_denylist: ["^https://target/admin/"]
Defensive patterns
Strategy: try-catch
Validate before calling
use ferox_scanner::url::should_deny_url;
if should_deny_url(&link_url, handles.clone())? {
log::info!("skipping denied link: {link_url}");
return Ok(()); // skip before calling request_link
} Try / catch
match extractor.request_link(&link_url).await {
Ok(_) => {}
Err(e) if e.to_string().starts_with("prevented request to") => {
log::debug!("link denied by denylist, skipping: {link_url}");
}
Err(e) => return Err(e),
} Prevention
- Keep denylist patterns anchored and specific; test them against expected crawled links
- Check the url/regex denylist values printed in the error when a link is unexpectedly skipped
- Treat this bail as informational during recursive scans when denial is intentional
- Review config-file denylist entries after schema/version changes
When it happens
Trigger: While crawling (request_links), the extractor discovers a link that matches --url-denylist or --regex-denylist (or config-file equivalents) and attempts to request it, triggering the bail.
Common situations: Users setting broad denylist patterns that also match links extracted from allowed pages (e.g. denying '/logout' that appears as a link everywhere); overly general regex like '.*admin.*' catching crawled pages; recursive scans following links into denied paths.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
AI-assisted analysis of epi052/feroxbuster@1f595dab5c (2026-09-13).
Data as JSON: /api/errors/7419a6ef148af826.
Report an issue: GitHub.
Appendix: source
Thrown at src/extractor/container.rs:51
let ferox_url = FeroxUrl::from_string(url, handles.clone());
// create a url based on the given command line options
let new_url = ferox_url.format("", None)?;
let scanned_urls = handles.ferox_scans()?;
if scanned_urls.get_scan_by_url(new_url.as_ref()).is_some() {
//we've seen the url before and don't need to scan again
log::trace!("exit: request_link -> None");
bail!("previously seen url");
}
if (!handles.config.url_denylist.is_empty() || !handles.config.regex_denylist.is_empty())
&& should_deny_url(&new_url, handles.clone())?
{
// can't allow a denied url to be requested
bail!(
"prevented request to {} due to {:?} || {:?}",
url,
handles.config.url_denylist,
handles.config.regex_denylist,
);
}
// make the request and store the response
let new_response = logged_request(&new_url, DEFAULT_METHOD, None, handles.clone()).await?;
log::trace!("exit: request_link -> {new_response:?}");
Ok(new_response)
}
/// Whether an active scan is recursive or not
#[derive(Debug, Copy, Clone)]
enum RecursionStatus {View on GitHub (pinned to 1f595dab5c)