{"record":{"id":"774d6be2e5c024f1","repo":"netbirdio/netbird","slug":"get-net-w","errorCode":null,"errorMessage":"get net: %w","messagePattern":"get net: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/embed/embed.go","lineNumber":357,"sourceCode":"\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tif c.config == nil {\n\t\treturn profilemanager.Config{}, ErrConfigNotInitialized\n\t}\n\treturn *c.config, nil\n}\n\n// Dial dials a network address in the netbird network.\n// Not applicable if the userspace networking mode is disabled.\nfunc (c *Client) Dial(ctx context.Context, network, address string) (net.Conn, error) {\n\tengine, err := c.getEngine()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tnsnet, err := engine.GetNet()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"get net: %w\", err)\n\t}\n\n\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","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/embed/embed.go#L339-L375","documentation":"Returned by Client.Dial when Engine.GetNet fails: either the WireGuard interface is not initialized yet (engine mid-teardown or not fully up) or the interface has no netstack (\"failed to get netstack\"), which is the expected condition when the client was created with NoUserspace=true (kernel mode has no userspace stack to dial from).","triggerScenarios":"Calling Dial after Start succeeded but with NoUserspace=true in Options; calling Dial concurrently with Stop so the interface is already torn down; calling Dial in the window before the interface is fully initialized.","commonSituations":"An embedding app that toggles NoUserspace for performance finds Dial/DialContext/NewHTTPClient all failing; races between an HTTP client built via NewHTTPClient and client shutdown; dialing right after Start returns on a slow engine.","solutions":["If you need Dial/NewHTTPClient, create the client with NoUserspace=false (the default userspace/netstack mode).","Guard calls with the client lifecycle: only dial between successful Start and Stop, and stop outstanding requests before Stop.","Retry briefly if the error is a transient not-yet-initialized window."],"exampleFix":"// before\nclient, err := embed.New(embed.Options{NoUserspace: true, ...})\nconn, err := client.Dial(ctx, \"tcp\", \"10.10.0.5:8080\")\n\n// after\nclient, err := embed.New(embed.Options{NoUserspace: false, ...})\nconn, err := client.Dial(ctx, \"tcp\", \"10.10.0.5:8080\")","handlingStrategy":"validation","validationCode":"if opts.NoUserspace {\n    return errors.New(\"dial APIs require userspace mode; set NoUserspace=false\")\n}","typeGuard":null,"tryCatchPattern":"conn, err := client.Dial(ctx, network, addr)\nif err != nil {\n    if errors.Is(err, embed.ErrClientNotStarted) || errors.Is(err, embed.ErrEngineNotStarted) || strings.Contains(err.Error(), \"get net\") {\n        // lifecycle/mode problem: not retried away by looping\n    }\n}","preventionTips":["Decide up front whether you need in-process dialing; if yes, never set NoUserspace=true.","Shut down http.Clients built from NewHTTPClient before calling Stop to avoid dial races."],"tags":["network","userspace","netstack","embed"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}