{"record":{"id":"ed3e7b23c83210e6","repo":"netbirdio/netbird","slug":"call-service-down-method-w","errorCode":null,"errorMessage":"call service down method: %w","messagePattern":"call service down method: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/profile.go","lineNumber":298,"sourceCode":"\t\tProfileName: &handle,\n\t\tUsername:    &currUser.Username,\n\t})\n\tif err != nil {\n\t\treturn wrapAmbiguityError(err, handle)\n\t}\n\n\tif err := profileManager.SwitchProfile(profilemanager.ID(switchResp.Id)); err != nil {\n\t\treturn err\n\t}\n\n\tstatus, err := daemonClient.Status(ctx, &proto.StatusRequest{})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"get service status: %w\", err)\n\t}\n\n\tif status.Status == string(internal.StatusConnected) {\n\t\tif _, err := daemonClient.Down(ctx, &proto.DownRequest{}); err != nil {\n\t\t\treturn fmt.Errorf(\"call service down method: %w\", err)\n\t\t}\n\t}\n\n\tid := profilemanager.ID(switchResp.Id)\n\tcmd.Printf(\"Profile switched to: %s\\n\", id.ShortID())\n\treturn nil\n}\n\n// wrapAmbiguityError turns the daemon's gRPC InvalidArgument errors\n// (which carry the resolver's message verbatim) into CLI-friendly text\n// that points the user at --show-id.\nfunc wrapAmbiguityError(err error, handle string) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\tst, ok := gstatus.FromError(err)\n\tif !ok {\n\t\treturn err","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/profile.go#L280-L316","documentation":"During `netbird profile select`, the daemon reported the peer Connected for the newly selected profile, and the subsequent Down RPC (issued so the old profile's tunnel comes down cleanly before you use the new one) failed. It runs on the same 7s context, so DeadlineExceeded under a slow teardown is the common cause; Unavailable appears if the daemon restarts mid-switch.","triggerScenarios":"Interface/firewall teardown taking longer than the remaining 7s budget; daemon restarting while switching; old profile's connection stuck so Down blocks; concurrent CLI command holding the daemon busy.","commonSituations":"Switching profiles on loaded machines; switching while the old tunnel is in a bad state; switching immediately after boot; running two CLI commands simultaneously.","solutions":["Retry `netbird profile select <handle>` after checking `netbird status`","If status shows Connected with the wrong profile, run `netbird down` then re-select","Inspect daemon logs for the Down failure (interface removal, firewall cleanup)","Avoid concurrent state-changing CLI calls during a switch"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# Before switching away from a connected profile, confirm daemon health\nnetbird status >/dev/null || exit 1\nnetbird profile select <handle> || netbird profile select <handle>  # one retry after settle","typeGuard":null,"tryCatchPattern":"if _, err := daemonClient.Down(ctx, &proto.DownRequest{}); err != nil {\n    if errors.Is(ctx.Err(), context.DeadlineExceeded) {\n        return fmt.Errorf(\"switch succeeded but teardown timed out; run `netbird down` if the old tunnel persists\")\n    }\n    return fmt.Errorf(\"call service down method: %w\", err)\n}","preventionTips":["Don't run other netbird state changes concurrently with profile select","If the old tunnel stays up after a timeout, run `netbird down` manually and re-select","Keep the daemon updated — teardown speed improves between releases"],"tags":["grpc","daemon","timeout","profiles","teardown"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}