netbirdio/netbird · error
create SSH proxy: %w
Error message
create SSH proxy: %w
What it means
sshproxy.New builds a gRPC client to the NetBird daemon using daemonaddr.DialTarget(daemonAddr) and grpc.NewClient. Because NewClient is lazy (non-blocking), this error almost always means the daemon address itself is invalid or cannot be turned into a dial target, not that the daemon is unreachable — connectivity problems surface later in Connect(). The underlying error is wrapped by sshproxy.New as 'connect to daemon: ...' and again here as 'create SSH proxy: ...'.
Source
Thrown at client/cmd/ssh.go:836
host := args[0]
portStr := args[1]
port, err := strconv.Atoi(portStr)
if err != nil {
return fmt.Errorf("invalid port: %s", portStr)
}
// Check env var for browser setting since this command is invoked via SSH ProxyCommand
// where command-line flags cannot be passed. Default is to open browser.
noBrowser := getBoolEnvOrDefault("NO_BROWSER", false)
var browserOpener func(string) error
if !noBrowser {
browserOpener = util.OpenBrowser
}
proxy, err := sshproxy.New(daemonAddr, host, port, cmd.ErrOrStderr(), browserOpener)
if err != nil {
return fmt.Errorf("create SSH proxy: %w", err)
}
defer func() {
if err := proxy.Close(); err != nil {
log.Debugf("close SSH proxy: %v", err)
}
}()
if err := proxy.Connect(cmd.Context()); err != nil {
return fmt.Errorf("SSH proxy: %w", err)
}
return nil
}
var sshDetectCmd = &cobra.Command{
Use: "detect <host> <port>",
Short: "Detect if a host is running NetBird SSH",
Long: "Internal command used by SSH Match exec to detect NetBird SSH servers. Exit codes: 0=JWT, 1=no-JWT, 2=regular SSH",View on GitHub (pinned to 93e97f4bf1)
Solutions
- Check NB_DAEMON_ADDR / --daemon-addr and use the documented form, e.g. unix:///var/run/netbird.sock (Unix) or the named pipe form on Windows
- Unset NB_DAEMON_ADDR to use the default daemon address
- Run `netbird status` with the same env to confirm the address is dialable at all
- Print the resolved daemonAddr before invoking ssh-proxy to catch empty or mangled values
Example fix
# before export NB_DAEMON_ADDR=/var/run/netbird.sock # missing unix:// scheme may fail target parsing # after export NB_DAEMON_ADDR=unix:///var/run/netbird.sock
Defensive patterns
Strategy: validation
Validate before calling
// fail fast on a malformed daemon address before sshproxy.New
if daemonAddr == "" {
return fmt.Errorf("daemon address is empty")
}
if _, _, err := daemonaddr.DialTarget(daemonAddr); err != nil { // or equivalent parse
return fmt.Errorf("invalid daemon address %q: %w", daemonAddr, err)
} Prevention
- Pin NB_DAEMON_ADDR in one shared script instead of ad-hoc exports
- Use the documented target forms (unix:///path/to.sock) and assert the socket file exists
- Smoke-test custom daemon addresses with `netbird status` before using ssh
When it happens
Trigger: NB_DAEMON_ADDR env var or --daemon-addr flag set to a malformed target: missing scheme on a unix path, bad characters, empty string after shell expansion, or a URL that fails target parsing on this platform.
Common situations: Pointing the CLI at a custom daemon socket (NB_DAEMON_ADDR=unix:///var/run/netbird.sock) with a typo; environments where the env var leaks a Windows-style pipe name into a Linux session; version changes in the accepted address formats.
Related errors
- address must be in [unix|tcp|npipe]://[path|host:port|name]
- unsupported daemon address protocol: %v
- client not initialized
- engine not started
- %s
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/f0aa777ca2f89c27.
Report an issue: GitHub.