epi052/feroxbuster · critical
failed to spawn a child process
Error message
failed to spawn a child process
What it means
wrapped_main spawns a helper child process (a binary) with tokio::process::Command to stream output. Command::spawn().expect(...) panics if the OS cannot spawn the child, producing 'failed to spawn a child process'.
Solutions
- Ensure the child binary exists and is executable at the resolved path (chmod +x)
- Raise container/sandbox rlimits (e.g. ulimit -u, docker --pids-limit) or allow process spawning in your security policy
- Check for PID exhaustion (too many processes) and free resources, then rerun
Example fix
// before (shell) ./feroxbuster # not executable / noexec volume // after (shell) chmod +x ./feroxbuster && ./feroxbuster
Defensive patterns
Strategy: retry
Validate before calling
let bin_ok = std::path::Path::new(&bin).exists(); let can_exec = bin_ok && std::fs::metadata(&bin).map(|m| m.permissions().readonly() == false).unwrap_or(false);
Type guard
fn spawnable(bin: &str) -> bool { std::path::Path::new(bin).exists() } Try / catch
match Command::new(&bin).args(&args).stdout(Stdio::piped()).spawn() {
Ok(child) => stream(child),
Err(e) => eprintln!("spawn failed ({e}); check binary path/permissions/limits"),
} Prevention
- Ensure the binary exists and has the execute bit set
- Raise rlimits/pids-limit in containers and CI sandboxes
- Avoid running from noexec-mounted volumes
When it happens
Trigger: Calling wrapped_main when the resolved child binary cannot be executed: binary missing at that path, missing execute permission, exec hitting resource limits (fork/ENOMEM, pid limits), or a seccomp/container policy blocking exec.
Common situations: Running inside minimal Docker images with restricted rlimits, sandboxed CI runners blocking process creation, or the binary having been moved/deleted while running.
Related errors
AI-assisted analysis of epi052/feroxbuster@1f595dab5c (2026-09-13).
Data as JSON: /api/errors/41cc5e0415f5f530.
Report an issue: GitHub.
Appendix: source
Thrown at src/main.rs:484
cloned[out_idx + 1] = full_path;
}
cloned.push("-u".to_string());
cloned.push(target);
let bin = cloned.index(0).to_owned(); // user's path to feroxbuster
let args = cloned.index(1..).to_vec(); // and args
let permit = PARALLEL_LIMITER.acquire().await?;
log::debug!("parallel exec: {} {}", bin, args.join(" "));
tokio::task::spawn(async move {
let mut output = Command::new(bin)
.args(&args)
.stdout(Stdio::piped())
.spawn()
.expect("failed to spawn a child process");
let stdout = output.stdout.take().unwrap();
let mut bufread = BufReader::new(stdout);
// output for a single line is a minimum of 51 bytes, so we'll start with that
// + a little wiggle room, and grow as needed
let mut buf: String = String::with_capacity(128);
while let Ok(n) = bufread.read_line(&mut buf) {
if n > 0 {
let trimmed = buf.trim();
if !trimmed.is_empty() {
println!("{trimmed}");
}
buf.clear();
} else {
break;
}View on GitHub (pinned to 1f595dab5c)