netbirdio/netbird · error
execute command: %w
Error message
execute command: %w
What it means
Returned by executeSSHCommand when the remote command fails for a reason other than the cases already handled: a non-zero remote exit is converted to os.Exit(ExitError.ExitStatus()), a missing exit status (ExitMissingError) is logged and treated as success, and context cancellation/deadline returns nil. Whatever remains — session setup failures, I/O errors on the channel, permission denied opening a session — is wrapped as `execute command: %w`.
Source
Thrown at client/cmd/ssh.go:590
}
if err != nil {
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
return nil
}
var exitErr *ssh.ExitError
if errors.As(err, &exitErr) {
os.Exit(exitErr.ExitStatus())
}
var exitMissingErr *ssh.ExitMissingError
if errors.As(err, &exitMissingErr) {
log.Debugf("Remote command exited without exit status: %v", err)
return nil
}
return fmt.Errorf("execute command: %w", err)
}
return nil
}
// openSSHTerminal opens an interactive SSH terminal.
func openSSHTerminal(ctx context.Context, c *sshclient.Client) error {
if err := c.OpenTerminal(ctx); err != nil {
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
return nil
}
var exitMissingErr *ssh.ExitMissingError
if errors.As(err, &exitMissingErr) {
log.Debugf("Remote terminal exited without exit status: %v", err)
return nil
}
return fmt.Errorf("open terminal: %w", err)View on GitHub (pinned to 93e97f4bf1)
Solutions
- Re-run the command; if it consistently fails while interactive `netbird ssh <host>` works, compare with and without --pty.
- Check peer health with `netbird status -d` and the remote sshd logs for rejected session/channel requests.
- Capture stderr of the CLI to see the wrapped cause after `execute command:` — it distinguishes channel I/O errors from protocol errors.
- If the command must surface the remote exit code, verify you are on a version where ExitError maps to os.Exit (non-zero exits propagate, this error is for the other failure modes).
- For scripted use, add a timeout with --timeout or wrap in timeout(1) so hangs surface as context errors (handled as nil/success) instead of channel errors.
Example fix
# before netbird ssh peer1 -- make build # -> execute command: session request failed # after netbird status -d # confirm peer healthy netbird ssh peer1 -- make build # retry once peer is responsive # or drop PTY for non-interactive commands: avoid --pty here
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight the command path before the interactive parts of a script
if command == "" {
return errors.New("no command given; pass it after the host")
}
if port < 1 || port > 65535 {
return fmt.Errorf("bad --port %d", port)
}
// confirm peer is reachable so exec failures are not connectivity noise
if !peerConnected(host) { return fmt.Errorf("peer %s not connected", host) } Try / catch
if err := executeSSHCommand(sshCtx, c, command); err != nil {
var exitErr *ssh.ExitError
switch {
case errors.As(err, &exitErr):
os.Exit(exitErr.ExitStatus()) // propagate remote exit code
case isExitMissing(err):
return nil // remote died without status: treat as done
case errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
return nil
default:
return fmt.Errorf("execute command: %w", err) // session/IO failure
}
} Prevention
- Skip --pty for non-interactive commands; PTY requests are the most commonly refused channel type.
- Wrap scripted runs in a deadline (timeout(1) or ctx) so hangs resolve as context errors instead of channel errors.
- Check `netbird status -d` before batch command execution across many peers.
- Design scripts to read the process exit code — non-zero remote exits already propagate via os.Exit; only transport failures reach this error.
When it happens
Trigger: `netbird ssh <host> <command...>` (optionally --pty) where the SSH session cannot be opened or the command stream fails mid-run: session channel rejected by the peer, stdin/stdout piping errors, terminal request refused when --pty is set, or the connection dropping during execution without a clean exit status.
Common situations: Running commands through a heavily loaded or half-dead peer; requesting a PTY for a non-interactive command on peers that restrict channel requests; piping large output that breaks the channel; commands killed by the remote side without an exit-status message.
Related errors
- dial %s: %w
- start port forwarding: %w
- open terminal: %w
- local port forward %s: %w
- remote port forward %s: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/9fb0d00e13c90603.
Report an issue: GitHub.