ginuerzh/gost · error
%s: %v
Error message
%s: %v
What it means
exeCmd runs a shell command built as a single string (split on spaces) and wraps any non-zero exit or spawn failure with the full command line and the underlying error. This library (tuntap) configures TUN/TAP interfaces by shelling out to system tools, so any failure of those tools surfaces as this wrapped error.
Source
Thrown at tuntap_linux.go:153
continue
}
cmd := fmt.Sprintf("ip route add %s via %s dev %s", route, gw, ifName)
log.Logf("[tap] %s", cmd)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
log.Logf("[tap] %s: %v", cmd, er)
}
}
return nil
}
func exeCmd(cmd string) error {
log.Log(cmd)
args := strings.Split(cmd, " ")
if err := exec.Command(args[0], args[1:]...).Run(); err != nil {
return fmt.Errorf("%s: %v", cmd, err)
}
return nil
}
View on GitHub (pinned to a33fdbf4c9)
Solutions
- Run the program as root or with CAP_NET_ADMIN so the networking command can succeed
- Install the required networking tool (iproute2) in the environment/container
- Check the wrapped %v message: 'executable file not found' means the tool is missing, 'operation not permitted' means insufficient privileges
- Print cfg values (Addr, MTU, Routes) to confirm no malformed input produced a broken command string
Example fix
// before
if err := exeCmd("ip addr add 10.0.0.1/24 dev tun0"); err != nil { ... } // run as non-root fails
// after
// run binary as root: sudo ./app (or grant: setcap cap_net_admin+ep ./app) Defensive patterns
Strategy: validation
Validate before calling
func canConfigureNet() error {
if os.Geteuid() != 0 {
return errors.New("tuntap: needs root/CAP_NET_ADMIN")
}
if _, err := exec.LookPath("ip"); err != nil {
return fmt.Errorf("tuntap: iproute2 missing: %w", err)
}
return nil
} Type guard
func cmdToolExists(name string) bool { _, err := exec.LookPath(name); return err == nil } Try / catch
if err := tun.CreateTun(cfg); err != nil {
var ee *exec.ExitError
if errors.As(err, &ee) {
log.Printf("netsetup failed: %s; stderr: %s", err, ee.Stderr)
}
if strings.Contains(err.Error(), "not found") { /* install tool */ }
if strings.Contains(err.Error(), "operation not permitted") { /* request privileges */ }
} Prevention
- Run the binary as root or grant cap_net_admin via setcap
- Ensure iproute2 (or the target tool) is present in your container image
- Never embed spaces-in-values in the command string; the library splits on spaces
- Log cfg fields before calling createTun/createTap to catch malformed input
When it happens
Trigger: exeCmd is called from createTun/createTap with a malformed command string, a missing binary (exec: "ip": executable file not found), or the command exits non-zero (e.g. permission denied configuring the interface).
Common situations: Running without root/CAP_NET_ADMIN; the required tool (e.g. `ip`) not installed on the Linux image (slim containers); interface name or CIDR containing characters that break the naive strings.Split(cmd, " ") parsing.
Related errors
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/7313f0b39e12fa8f.
Report an issue: GitHub.