epi052/feroxbuster · error

Couldn't start file handler

Error message

Couldn't start {} file handler

What it means

FeroxScan's main entry point spawns a dedicated file-output handler task that writes scan results to the file specified via -o/--output. Before scanning begins, wrapped_main sends a sync message to that handler to verify the tx/rx channel works. If the sync fails, the file handler never started, so the tool aborts with this message naming the configured output path.

Solutions

  1. Verify the directory of the -o path exists and is writable by the feroxbuster process
  2. Remove any conflicting file/directory at the output path or choose a new path
  3. Re-run with absolute output path to rule out CWD differences
  4. If the path is fine, check system resource limits (fd limits, spawn failures) and report upstream

Example fix

// before
feroxbuster -u https://target -o /root/scan-results/out.json
// after
mkdir -p /root/scan-results && chmod u+w /root/scan-results
feroxbuster -u https://target -o /root/scan-results/out.json
Defensive patterns

Strategy: validation

Validate before calling

let p = std::path::Path::new(out_path);
if let Some(dir) = p.parent() {
    anyhow::ensure!(dir.exists(), "output dir {} does not exist", dir.display());
}
anyhow::ensure!(!p.is_dir(), "output path {} is a directory", out_path);

Prevention

When it happens

Trigger: Running feroxbuster with an output file (-o/--output FILE) while FileOutHandler::start fails to initialize or its channel is unresponsive when output.sync() is awaited in wrapped_main.

Common situations: The output path points to a non-existent or unwritable directory, the file exists but the process lacks write permission, the path is a directory, or disk/resource constraints prevent spawning the handler task.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at src/main.rs:562

        let _ = banner.check_for_updates(UPDATE_URL, handles.clone()).await;

        if banner.print_to(std_stderr, config.clone()).is_err() {
            clean_up(handles, tasks).await?;
            bail!(fmt_err("Could not print banner"));
        }
    }

    {
        let send_to_file = !config.output.is_empty();

        // The TermOutHandler spawns a FileOutHandler, so errors in the FileOutHandler never bubble
        // up due to the TermOutHandler never awaiting the result of FileOutHandler::start (that's
        // done later here in main). sync checks that the tx/rx connection to the file handler works
        if send_to_file && handles.output.sync(send_to_file).await.is_err() {
            // output file specified and file handler could not initialize
            clean_up(handles, tasks).await?;
            let msg = format!("Couldn't start {} file handler", config.output);
            bail!(fmt_err(&msg));
        }
    }

    // discard non-responsive targets
    let live_targets = {
        let test = heuristics::HeuristicTests::new(handles.clone());
        let result = test.connectivity(&targets).await;
        if let Err(err) = result {
            clean_up(handles, tasks).await?;
            bail!(fmt_err(&err.to_string()));
        }
        result?
    };

    if live_targets.is_empty() {
        clean_up(handles, tasks).await?;
        bail!(fmt_err("Could not find any live targets to scan"));
    }

View on GitHub (pinned to 1f595dab5c)