epi052/feroxbuster · error

[ ] Unable to download wordlist from url

Error message

[{}] Unable to download wordlist from url: {}

What it means

When a wordlist is given as a remote URL, wrapped_main downloads it via a reqwest GET; if the response status is not a success (non-2xx), it bails with this message, prefixing the HTTP status code and the source URL. The scan aborts because the wordlist could not be fetched.

Solutions

  1. Open the wordlist URL in a browser/curl to confirm it returns 200
  2. Fix the URL (moved files, correct branch/tag for raw GitHub links)
  3. Download the wordlist locally and pass a file path instead of a URL
  4. Add required auth/headers via proxy or fetch manually if the host needs credentials

Example fix

// before
ferox -u https://t.com --wordlist https://example.com/lists/common.txt  // 404
// after
wget https://raw.githubusercontent.com/.../common.txt && ferox -u https://t.com --wordlist ./common.txt
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await fetch(wordlistUrl); if (!res.ok) throw new Error(`wordlist URL returned ${res.status}`);

Try / catch

catch (e) { if (String(e).includes('Unable to download wordlist')) { /* verify URL manually, fall back to local wordlist */ } }

Prevention

When it happens

Trigger: --wordlist https://... returns 404/403/500, or the hosting server requires auth, rate-limits, or blocks the client so response.status().is_success() is false.

Common situations: Pointing at a GitHub raw URL that moved or a private repo (404/403), a URL behind a login, a corporate proxy returning 407, or a deleted gist.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of epi052/feroxbuster@1f595dab5c (2026-09-13). Data as JSON: /api/errors/0fd1c32753edd748. Report an issue: GitHub.

Appendix: source

Thrown at src/main.rs:268

        // supplied them, so the merged ordering is deterministic.
        let mut words = vec![String::from("")];
        let mut seen = std::collections::HashSet::new();
        seen.insert(String::new());

        let single_local_source =
            config.wordlist.len() == 1 && !config.wordlist[0].starts_with("http");

        for source in &config.wordlist {
            if source.starts_with("http") {
                // found a url scheme, attempt to download the wordlist
                let response = config.client.get(source).send().await.context(format!(
                    "Unable to download wordlist from remote url: {source}"
                ))?;

                if !response.status().is_success() {
                    // status code isn't a 200, bail
                    bail!(
                        "[{}] Unable to download wordlist from url: {}",
                        response.status().as_str(),
                        source
                    );
                }

                // attempt to get the filename from the url's path
                let Some(mut path_segments) = response.url().path_segments() else {
                    bail!("Unable to parse path from url: {}", response.url());
                };

                let Some(filename) = path_segments.next_back() else {
                    bail!(
                        "Unable to parse filename from url's path: {}",
                        response.url().path()
                    );
                };

                let filename = filename.to_string();

View on GitHub (pinned to 1f595dab5c)