{"record":{"id":"3ab1f6e5b03b69dc","repo":"netbirdio/netbird","slug":"wait-for-extend-session-v","errorCode":null,"errorMessage":"wait for extend session: %v","messagePattern":"wait for extend session: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/login.go","lineNumber":219,"sourceCode":"\t}\n\n\tstartResp, err := client.RequestExtendAuthSession(ctx, req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"start extend session: %v\", err)\n\t}\n\n\turi := startResp.GetVerificationURIComplete()\n\tif uri == \"\" {\n\t\turi = startResp.GetVerificationURI()\n\t}\n\topenURL(cmd, uri, startResp.GetUserCode(), noBrowser, showQR)\n\n\twaitResp, err := client.WaitExtendAuthSession(ctx, &proto.WaitExtendAuthSessionRequest{\n\t\tDeviceCode: startResp.GetDeviceCode(),\n\t\tUserCode:   startResp.GetUserCode(),\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"wait for extend session: %v\", err)\n\t}\n\n\tif ts := waitResp.GetSessionExpiresAt(); ts.IsValid() && !ts.AsTime().IsZero() {\n\t\tdeadline := ts.AsTime().Local()\n\t\tcmd.Printf(\"Session extended. New expiry: %s\\n\", deadline.Format(\"2006-01-02 15:04:05 MST\"))\n\t} else {\n\t\t// Management reported the peer is not eligible (e.g. login\n\t\t// expiration disabled on the account). Surface that fact\n\t\t// instead of pretending the call succeeded.\n\t\tcmd.Println(\"Session extension call completed, but the management server did not return a new deadline (peer may not be SSO-tracked or login expiration is disabled).\")\n\t}\n\treturn nil\n}\n\nfunc getActiveProfile(ctx context.Context, pm *profilemanager.ProfileManager, profileName string, username string) (*profilemanager.Profile, error) {\n\t// switch profile if provided\n\n\tif profileName != \"\" {","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/login.go#L201-L237","documentation":"Wraps a failure of client.WaitExtendAuthSession, a long-poll gRPC call to the NetBird daemon (unix socket /var/run/netbird.sock or Windows named pipe) that blocks until the user finishes device-code auth in a browser. The error is either a transport failure (daemon stopped, connection dropped mid-wait, ctx cancelled via Ctrl+C) or a daemon-side error propagated from management while extending the login session (peer not connected, management unreachable).","triggerScenarios":"Calling 'netbird login --extend-session' (or the extend flow) and: cancelling the command before completing browser auth; daemon restarted or crashed while the CLI was blocked in WaitExtendAuthSession; device code expiring server-side; daemon not connected to management so the extension request fails.","commonSituations":"Daemon stopped mid-wait (netbird service stop, OOM kill, package upgrade restarting the service); management server unreachable from the daemon host; slow browser auth in SSH sessions where the code expires; running the CLI as a user without access to the daemon socket.","solutions":["Check the daemon is running: 'netbird service status' (or systemctl status netbird) and 'netbird service start' if not; then rerun the command","Inspect daemon logs (journalctl -u netbird or the daemon log file) for the underlying management error surfaced by the RPC","Verify the daemon can reach the management URL (network, firewall, DNS) and that the peer shows Connected in 'netbird status'","If the code expired or auth was aborted, rerun and complete the browser step promptly"],"exampleFix":"// before\nwaitResp, err := client.WaitExtendAuthSession(ctx, &proto.WaitExtendAuthSessionRequest{...})\nif err != nil {\n    return fmt.Errorf(\"wait for extend session: %v\", err)\n}\n\n// after: distinguish user cancel / daemon down from server-side denial\nwaitResp, err := client.WaitExtendAuthSession(ctx, &proto.WaitExtendAuthSessionRequest{...})\nif err != nil {\n    switch status.Code(err) {\n    case codes.Canceled:\n        return fmt.Errorf(\"extend session canceled: %w\", err)\n    case codes.Unavailable:\n        return fmt.Errorf(\"daemon unreachable, run 'netbird service start': %w\", err)\n    default:\n        return fmt.Errorf(\"wait for extend session: %w\", err)\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Probe the daemon before starting the extend flow\nconn, err := DialClientGRPCServer(ctx, daemonAddr)\nif err != nil {\n    return fmt.Errorf(\"daemon not reachable: %w\", err)\n}\nclient := proto.NewDaemonServiceClient(conn)\nif _, err := client.Status(ctx, &proto.StatusRequest{}); err != nil {\n    return fmt.Errorf(\"daemon not ready: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := waitExtend(ctx); err != nil {\n    switch status.Code(err) {\n    case codes.Canceled, codes.DeadlineExceeded:\n        // user abort or expiry: safe to retry the whole flow\n        return retryExtend(ctx)\n    case codes.Unavailable:\n        return fmt.Errorf(\"daemon down, run 'netbird service start': %w\", err)\n    default:\n        return fmt.Errorf(\"wait for extend session: %w\", err)\n    }\n}","preventionTips":["Run 'netbird service status' before any login/extend command","Avoid Ctrl+C during the browser-wait phase; let it finish or expire cleanly","Keep the daemon and management versions compatible when upgrading"],"tags":["grpc","daemon","session-extension","cli","netbird"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}