netbirdio/netbird · error
start port forwarding: %w
Error message
start port forwarding: %w
What it means
Returned by runSSH when startPortForwarding fails before the interactive session or remote command starts. startPortForwarding only iterates the -L/--local-forward and -R/--remote-forward flag values and delegates to parseAndStartLocalForward/parseAndStartRemoteForward, so this error always wraps either a parsePortForwardSpec failure (malformed spec) or a validateDestinationPort failure (bad/zero/out-of-range port) — the connection itself is already up at this point.
Source
Thrown at client/cmd/ssh.go:556
cmd.Printf("\nTroubleshooting steps:\n")
cmd.Printf(" 1. Check peer connectivity: netbird status -d\n")
cmd.Printf(" 2. Verify SSH server is enabled on the peer\n")
cmd.Printf(" 3. Ensure correct hostname/IP is used\n")
return fmt.Errorf("dial %s: %w", target, err)
}
sshCtx, cancel := context.WithCancel(ctx)
defer cancel()
go func() {
<-sshCtx.Done()
if err := c.Close(); err != nil {
cmd.Printf("Error closing SSH connection: %v\n", err)
}
}()
if err := startPortForwarding(sshCtx, c, cmd); err != nil {
return fmt.Errorf("start port forwarding: %w", err)
}
if command != "" {
return executeSSHCommand(sshCtx, c, command)
}
return openSSHTerminal(sshCtx, c)
}
// executeSSHCommand executes a command over SSH.
func executeSSHCommand(ctx context.Context, c *sshclient.Client, command string) error {
var err error
if requestPTY {
err = c.ExecuteCommandWithPTY(ctx, command)
} else {
err = c.ExecuteCommandWithIO(ctx, command)
}
if err != nil {View on GitHub (pinned to 93e97f4bf1)
Solutions
- Read the wrapped message: `start port forwarding: local port forward <spec>: ...` or `remote port forward <spec>: ...` tells you which flag and spec failed.
- Fix the spec to one of the accepted forms: [local_host:]local_port:remote_target with 2-4 colon parts (2-part only valid as port:/unix/socket), e.g. -L 8080:localhost:80.
- Give the destination a concrete port 1-65535; 0 is only valid on the bind side, not the destination.
- Bracket IPv6 local hosts: -L [::1]:8080:host:80.
- Re-run; parsing happens after dial, so no reconnect cost concerns — the failure is purely local input validation.
Example fix
# before netbird ssh -L 8080:remotehost peer1 # -> start port forwarding: local port forward 8080:remotehost: invalid port forward specification ... # after netbird ssh -L 8080:remotehost:80 peer1
Defensive patterns
Strategy: validation
Validate before calling
// validate every -L/-R spec before invoking netbird ssh
func validateForwardSpecs(specs []string) error {
for _, s := range specs {
parts := strings.Split(s, ":")
if len(parts) < 2 || len(parts) > 4 {
return fmt.Errorf("spec %q must have 2-4 colon parts", s)
}
}
return nil
}
// plus run the same validateDestinationPort logic from error 371 on the destination Try / catch
if err := startPortForwarding(sshCtx, c, cmd); err != nil {
// err always wraps a parse/port validation failure of one spec;
// the session is still up: log, skip the bad spec or abort per policy
log.Printf("forwarding setup failed: %v", err)
} Prevention
- Keep a single canonical forward-spec builder function in your tooling so every script emits the same 2-4 part grammar.
- Unit-test the spec strings (go test with table-driven cases) when forwards are generated from config.
- Quote each -L/-R argument so colons survive every shell/config layer.
- Fail fast on the first invalid spec in wrappers — the CLI stops at the first one anyway.
When it happens
Trigger: `netbird ssh -L <bad-spec> host` or `-R <bad-spec>` where the spec has fewer than 2 or more than 4 colon-separated parts, uses a two-part host form without a unix socket path, or where the destination address fails port validation (unparseable, non-numeric, 0, or >65535).
Common situations: Copy-pasting OpenSSH forward syntax with extra segments; forgetting the remote port in `8080:host`; using port 0 expecting the OS to pick a port on the destination side (only valid for bind side); IPv6 addresses passed unbracketed so colon counting breaks.
Related errors
- local port forward %s: %w
- remote port forward %s: %w
- invalid remote address: %w
- invalid local address: %w
- invalid port forward specification: %s (expected format: [lo
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/e66b03b008f7a9cf.
Report an issue: GitHub.