{"record":{"id":"8c116d7f18984e04","repo":"netbirdio/netbird","slug":"split-host-port-w","errorCode":null,"errorMessage":"split host port: %w","messagePattern":"split host port: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/embed/embed.go","lineNumber":378,"sourceCode":"\treturn nsnet.DialContext(ctx, network, address)\n}\n\n// DialContext dials a network address in the netbird network with context\nfunc (c *Client) DialContext(ctx context.Context, network, address string) (net.Conn, error) {\n\treturn c.Dial(ctx, network, address)\n}\n\n// ListenTCP listens on the given address in the netbird network.\n// Not applicable if the userspace networking mode is disabled.\nfunc (c *Client) ListenTCP(address string) (net.Listener, error) {\n\tnsnet, addr, err := c.getNet()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t_, port, err := net.SplitHostPort(address)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"split host port: %w\", err)\n\t}\n\tlistenAddr := net.JoinHostPort(addr.String(), port)\n\n\ttcpAddr, err := net.ResolveTCPAddr(\"tcp\", listenAddr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"resolve: %w\", err)\n\t}\n\treturn nsnet.ListenTCP(tcpAddr)\n}\n\n// ListenUDP listens on the given address in the netbird network.\n// Not applicable if the userspace networking mode is disabled.\nfunc (c *Client) ListenUDP(address string) (net.PacketConn, error) {\n\tnsnet, addr, err := c.getNet()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/embed/embed.go#L360-L396","documentation":"Returned by Client.ListenTCP when net.SplitHostPort cannot parse the address argument. The listen address must include a port: a bare host (\"svc\"), a bare port (\"8080\" without colon), or an IPv6 literal with multiple unbracketed colons all fail here. Note the host part is discarded anyway: the client always binds its own overlay IP, so only the port matters.","triggerScenarios":"ListenTCP(\"8080\"), ListenTCP(\"localhost\") (no port), or ListenTCP(\"fd00::1:8080\") without brackets around the IPv6 part.","commonSituations":"Passing a port-only integer as a string assuming it is accepted; forwarding a user-entered address that omitted the port; IPv6 addresses from config not normalized to bracket form.","solutions":["Always pass host:port or the convenient \":port\" form: ListenTCP(\":8080\").","Normalize user input with net.SplitHostPort (or net.JoinHostPort when building) before calling ListenTCP.","Bracket IPv6 literals: \"[fd00::1]:8080\"."],"exampleFix":"// before\nln, err := client.ListenTCP(\"8080\")\n\n// after\nln, err := client.ListenTCP(\":8080\")","handlingStrategy":"validation","validationCode":"if _, _, err := net.SplitHostPort(address); err != nil {\n    address = \":\" + strings.TrimPrefix(address, \":\") // or reject: require host:port\n    // simplest robust fix: address = net.JoinHostPort(\"\", portStr)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize on the \":port\" form for ListenTCP/ListenUDP since the host is replaced anyway.","Build addresses with net.JoinHostPort, never string concatenation."],"tags":["network","validation","listen","embed"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}