seaweedfs/seaweedfs · error
master process can not start child process: %s
Error message
master process can not start child process: %s
What it means
runFuse in weed/command/fuse_std.go parses FUSE helper-style options (space/dash/comma separated name=value pairs, e.g. `weed fuse /mnt/sw -o filer=localhost:8888,readOnly=true`) before daemonizing into a master/child pair and calling runMount. In master mode the helper resolves its own executable with os.Executable() and re-execs it as a child with `-o child=<pid>` appended; this panic means os.StartProcess failed, i.e. the weed binary could not be exec'd again. Typical errno causes: ENOENT (binary deleted or renamed over after start), EACCES (exec bit lost, or binary sits on a noexec mount), EAGAIN (RLIMIT_NPROC or cgroup pids.max exhausted), ETXTBSY (binary being rewritten concurrently), plus SELinux/apparmor/seccomp denials.
Source
Thrown at weed/command/fuse_std.go:322
arg0, err := os.Executable()
if err != nil {
panic(err)
}
// pass our PID to the child process
pid := os.Getpid()
argv := append(os.Args, "-o", "child="+strconv.Itoa(pid))
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGTERM)
attr := os.ProcAttr{}
attr.Env = os.Environ()
child, err := os.StartProcess(arg0, argv, &attr)
if err != nil {
panic(fmt.Errorf("master process can not start child process: %s", err))
}
err = child.Release()
if err != nil {
panic(fmt.Errorf("master process can not release child process: %s", err))
}
select {
case <-c:
return true
}
}
if fusermountPath != "" {
if err := os.Setenv("PATH", fusermountPath); err != nil {
panic(fmt.Errorf("setenv: %s", err))
}View on GitHub (pinned to 1c926e8fac)
Solutions
- Confirm the binary resolves and is executable: ls -l $(command -v weed) and test -x
- Invoke weed via a stable absolute path from a location that is not rewritten during deploys
- Raise process limits (ulimit -u, cgroup pids.max) if fork fails with 'resource temporarily unavailable'
- Check for noexec mount flags and SELinux/apparmor denials on the binary path
- Bypass the re-exec entirely with `weed mount -dir=... -filer=...`, which mounts directly
Example fix
// before /tmp/deploy-old/weed fuse /mnt/sw -o filer=localhost:8888 # binary path replaced/deleted at deploy time // after /opt/seaweedfs/bin/weed fuse /mnt/sw -o filer=localhost:8888 # stable absolute path, exec bit intact
Defensive patterns
Strategy: validation
Validate before calling
# bash: verify the helper can re-exec itself before mounting
exe="$(command -v weed)"
[ -n "$exe" ] && [ -x "$exe" ] || { echo "weed binary not executable: $exe" >&2; exit 1; }
readlink -f "$exe" >/dev/null || exit 1 Type guard
func canReexecSelf() error {
exe, err := os.Executable()
if err != nil {
return err
}
fi, err := os.Stat(exe)
if err != nil {
return fmt.Errorf("cannot stat %s: %w", exe, err)
}
if fi.IsDir() || fi.Mode()&0o111 == 0 {
return fmt.Errorf("%s is not executable", exe)
}
return nil
} Prevention
- Deploy weed to a versioned absolute path and symlink a stable name to it
- Never chmod -x or delete the running binary's path during upgrades
- Size container pids.max above the helper's master+child pair
- Prefer `weed mount` for environments where re-exec is restricted
When it happens
Trigger: Package upgrade renames a new weed binary over the running path before the re-exec; container with pids.max nearly exhausted; weed placed on a noexec filesystem or with chmod -x; hardened seccomp profile blocking fork/exec in CI.
Common situations: CI containers with tight pid limits; deployment scripts that mv/rm the binary then start mounts from the old path; security-hardened hosts denying exec of non-standard paths.
Related errors
- master process can not release child process: %s
- setenv: %s
- parent PID %d is invalid
- parent PID %s is invalid: %w
- dirAutoCreate: %s
AI-assisted analysis of seaweedfs/seaweedfs@1c926e8fac (2026-08-15).
Data as JSON: /api/errors/e8445b0bd2b3baaf.
Report an issue: GitHub.