{"record":{"id":"5505a49893793a63","repo":"netbirdio/netbird","slug":"invalid-port-s","errorCode":null,"errorMessage":"invalid port: %s","messagePattern":"invalid port: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/cmd/ssh.go","lineNumber":823,"sourceCode":"}\n\nfunc sshProxyFn(cmd *cobra.Command, args []string) error {\n\tlogOutput := \"console\"\n\tif firstLogFile := util.FindFirstLogPath(logFiles); firstLogFile != \"\" && firstLogFile != defaultLogFile {\n\t\tlogOutput = firstLogFile\n\t}\n\n\tproxyLogLevel := getEnvOrDefault(\"LOG_LEVEL\", logLevel)\n\tif err := util.InitLog(proxyLogLevel, logOutput); err != nil {\n\t\treturn fmt.Errorf(\"init log: %w\", err)\n\t}\n\n\thost := args[0]\n\tportStr := args[1]\n\n\tport, err := strconv.Atoi(portStr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid port: %s\", portStr)\n\t}\n\n\t// Check env var for browser setting since this command is invoked via SSH ProxyCommand\n\t// where command-line flags cannot be passed. Default is to open browser.\n\tnoBrowser := getBoolEnvOrDefault(\"NO_BROWSER\", false)\n\tvar browserOpener func(string) error\n\tif !noBrowser {\n\t\tbrowserOpener = util.OpenBrowser\n\t}\n\n\tproxy, err := sshproxy.New(daemonAddr, host, port, cmd.ErrOrStderr(), browserOpener)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create SSH proxy: %w\", err)\n\t}\n\tdefer func() {\n\t\tif err := proxy.Close(); err != nil {\n\t\t\tlog.Debugf(\"close SSH proxy: %v\", err)\n\t\t}","sourceCodeStart":805,"sourceCodeEnd":841,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/ssh.go#L805-L841","documentation":"ssh-proxy takes exactly two positional arguments, host and port, and the port is parsed with strconv.Atoi. Any non-decimal port (letters, empty string, a service name like 'ssh', or a trailing newline from shell expansion) makes Atoi fail and the command aborts with 'invalid port: <value>'.","triggerScenarios":"SSH ProxyCommand template that omits %p or substitutes the wrong token; passing 'ssh' instead of 22; port passed as '22\\r' from a Windows/CR-terminated config; quoting that glues host and port together so args[1] is wrong.","commonSituations":"Hand-edited ~/.ssh/config with ProxyCommand netbird ssh-proxy %h (missing %p); automation scripts that compute the port with a command substitution returning an empty or non-numeric value.","solutions":["Fix the ProxyCommand line to pass both tokens: ProxyCommand netbird ssh-proxy %h %p","Ensure the port argument is a plain decimal number (e.g. 22, 2222), not a service name","Check for stray whitespace/CR in the generated command by running ssh with -vvv and inspecting the executed ProxyCommand","Echo the exact command your wrapper builds and run netbird ssh-proxy host port by hand"],"exampleFix":"# before\nHost mypeer\n  ProxyCommand netbird ssh-proxy %h\n\n# after\nHost mypeer\n  ProxyCommand netbird ssh-proxy %h %p","handlingStrategy":"validation","validationCode":"port, err := strconv.Atoi(strings.TrimSpace(portStr))\nif err != nil || port < 1 || port > 65535 {\n    return fmt.Errorf(\"port must be a decimal 1-65535, got %q\", portStr)\n}","typeGuard":"func isValidPort(s string) bool {\n    p, err := strconv.Atoi(strings.TrimSpace(s))\n    return err == nil && p >= 1 && p <= 65535\n}","tryCatchPattern":null,"preventionTips":["Always use %h %p tokens in ProxyCommand; never hardcode or omit the port","Validate generated commands in scripts before exec: numeric host-independant port check","Avoid service names; resolve them to numbers first"],"tags":["go","cli","ssh","validation","proxycommand"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}