netbirdio/netbird · error
remote port forward %s: %w
Error message
remote port forward %s: %w
What it means
Returned by startPortForwarding when parseAndStartRemoteForward rejects one -R/--remote-forward spec. Structurally identical to the local case: the wrap names the failing spec and the cause is either parsePortForwardSpec (colon structure) or validateDestinationPort applied to the local address — in the -R flow the 'destination' the validator checks is the localAddr the remote side will dial back to.
Source
Thrown at client/cmd/ssh.go:623
return nil
}
return fmt.Errorf("open terminal: %w", err)
}
return nil
}
// startPortForwarding starts local and remote port forwarding based on command line flags
func startPortForwarding(ctx context.Context, c *sshclient.Client, cmd *cobra.Command) error {
for _, forward := range localForwards {
if err := parseAndStartLocalForward(ctx, c, forward, cmd); err != nil {
return fmt.Errorf("local port forward %s: %w", forward, err)
}
}
for _, forward := range remoteForwards {
if err := parseAndStartRemoteForward(ctx, c, forward, cmd); err != nil {
return fmt.Errorf("remote port forward %s: %w", forward, err)
}
}
return nil
}
// parseAndStartLocalForward parses and starts a local port forward (-L)
func parseAndStartLocalForward(ctx context.Context, c *sshclient.Client, forward string, cmd *cobra.Command) error {
localAddr, remoteAddr, err := parsePortForwardSpec(forward)
if err != nil {
return err
}
if err := validateDestinationPort(remoteAddr); err != nil {
return fmt.Errorf("invalid remote address: %w", err)
}
log.Debugf("Local port forwarding: %s -> %s", localAddr, remoteAddr)View on GitHub (pinned to 93e97f4bf1)
Solutions
- Use the accepted forms with the local target fully specified: -R [remote_host:]remote_port:local_host:local_port, local port 1-65535 (e.g., -R 9000:localhost:8080).
- Give the local endpoint a concrete non-zero port — 0 is rejected because the remote side must connect to something definite.
- Bracket IPv6 bind hosts and keep the spec to 2-4 colon parts.
- Check the wrapped tail (`invalid local address: ...`) to see exactly which sub-check failed, then fix that segment.
Example fix
# before netbird ssh -R 9000:localhost peer1 # -> start port forwarding: remote port forward 9000:localhost: invalid port forward specification ... # after netbird ssh -R 9000:localhost:8080 peer1
Defensive patterns
Strategy: validation
Validate before calling
// -R grammar: [remote_host:]remote_port:local_host:local_port
func buildRemoteForward(remotePort int, localHost string, localPort int) (string, error) {
if remotePort < 1 || remotePort > 65535 || localPort < 1 || localPort > 65535 {
return "", fmt.Errorf("ports must be 1-65535, got remote=%d local=%d", remotePort, localPort)
}
if localHost == "" {
localHost = "127.0.0.1"
}
return fmt.Sprintf("%d:%s:%d", remotePort, localHost, localPort), nil
} Try / catch
if err := parseAndStartRemoteForward(ctx, c, forward, cmd); err != nil {
// parse or local-endpoint port validation failed on this spec;
// report and continue/abort — no listener was created for it
log.Printf("skip remote forward %q: %v", forward, err)
} Prevention
- Remember -R's tail is the LOCAL endpoint your machine serves — give it host:port explicitly, never 0.
- Use numeric ports only; service names are rejected by Atoi.
- In templates, default unset local ports to the service's real port, not 0 or empty.
- Pre-validate with the same colon-count and port-range checks you use for -L.
When it happens
Trigger: `netbird ssh -R 9000:localhost peer` (two parts, second not a unix path), `-R 9000:localhost:0` (local port 0), `-R 9000:localhost:70000` (out of range), `-R bindhost:9000:localhost:80:extra` (5 parts), or any spec whose validated local endpoint fails SplitHostPort/Atoi/range checks.
Common situations: Mirroring an OpenSSH -R habit of omitting the local port; expecting the remote side to pick the port; specs built from variables where one segment is empty; forgetting that in -R the last host:port pair is the local target your machine serves.
Related errors
- start port forwarding: %w
- local 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/9d76e28984b0aab5.
Report an issue: GitHub.