{"record":{"id":"e66b03b008f7a9cf","repo":"netbirdio/netbird","slug":"start-port-forwarding-w","errorCode":null,"errorMessage":"start port forwarding: %w","messagePattern":"start port forwarding: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/ssh.go","lineNumber":556,"sourceCode":"\t\tcmd.Printf(\"\\nTroubleshooting steps:\\n\")\n\t\tcmd.Printf(\"  1. Check peer connectivity: netbird status -d\\n\")\n\t\tcmd.Printf(\"  2. Verify SSH server is enabled on the peer\\n\")\n\t\tcmd.Printf(\"  3. Ensure correct hostname/IP is used\\n\")\n\t\treturn fmt.Errorf(\"dial %s: %w\", target, err)\n\t}\n\n\tsshCtx, cancel := context.WithCancel(ctx)\n\tdefer cancel()\n\n\tgo func() {\n\t\t<-sshCtx.Done()\n\t\tif err := c.Close(); err != nil {\n\t\t\tcmd.Printf(\"Error closing SSH connection: %v\\n\", err)\n\t\t}\n\t}()\n\n\tif err := startPortForwarding(sshCtx, c, cmd); err != nil {\n\t\treturn fmt.Errorf(\"start port forwarding: %w\", err)\n\t}\n\n\tif command != \"\" {\n\t\treturn executeSSHCommand(sshCtx, c, command)\n\t}\n\treturn openSSHTerminal(sshCtx, c)\n}\n\n// executeSSHCommand executes a command over SSH.\nfunc executeSSHCommand(ctx context.Context, c *sshclient.Client, command string) error {\n\tvar err error\n\tif requestPTY {\n\t\terr = c.ExecuteCommandWithPTY(ctx, command)\n\t} else {\n\t\terr = c.ExecuteCommandWithIO(ctx, command)\n\t}\n\n\tif err != nil {","sourceCodeStart":538,"sourceCodeEnd":574,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/ssh.go#L538-L574","documentation":"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.","triggerScenarios":"`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).","commonSituations":"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.","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."],"exampleFix":"# before\nnetbird ssh -L 8080:remotehost peer1\n# -> start port forwarding: local port forward 8080:remotehost: invalid port forward specification ...\n\n# after\nnetbird ssh -L 8080:remotehost:80 peer1","handlingStrategy":"validation","validationCode":"// validate every -L/-R spec before invoking netbird ssh\nfunc validateForwardSpecs(specs []string) error {\n\tfor _, s := range specs {\n\t\tparts := strings.Split(s, \":\")\n\t\tif len(parts) < 2 || len(parts) > 4 {\n\t\t\treturn fmt.Errorf(\"spec %q must have 2-4 colon parts\", s)\n\t\t}\n\t}\n\treturn nil\n}\n// plus run the same validateDestinationPort logic from error 371 on the destination","typeGuard":null,"tryCatchPattern":"if err := startPortForwarding(sshCtx, c, cmd); err != nil {\n\t// err always wraps a parse/port validation failure of one spec;\n\t// the session is still up: log, skip the bad spec or abort per policy\n\tlog.Printf(\"forwarding setup failed: %v\", err)\n}","preventionTips":["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."],"tags":["go","ssh","port-forwarding","validation","cli"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}