netbirdio/netbird · error
get service status: %w
Error message
get service status: %w
What it means
During `netbird profile select`, after SwitchProfile succeeded, the follow-up daemonClient.Status RPC failed. The whole select flow runs under the 7s context created in selectProfileFunc, so a daemon that is mid-restart (switching profiles can cause reconnection work) or a busy daemon can exceed it. The %w wrap keeps the gRPC status (often DeadlineExceeded or Unavailable).
Source
Thrown at client/cmd/profile.go:293
defer conn.Close()
daemonClient := proto.NewDaemonServiceClient(conn)
switchResp, err := daemonClient.SwitchProfile(ctx, &proto.SwitchProfileRequest{
ProfileName: &handle,
Username: &currUser.Username,
})
if err != nil {
return wrapAmbiguityError(err, handle)
}
if err := profileManager.SwitchProfile(profilemanager.ID(switchResp.Id)); err != nil {
return err
}
status, err := daemonClient.Status(ctx, &proto.StatusRequest{})
if err != nil {
return fmt.Errorf("get service status: %w", err)
}
if status.Status == string(internal.StatusConnected) {
if _, err := daemonClient.Down(ctx, &proto.DownRequest{}); err != nil {
return fmt.Errorf("call service down method: %w", err)
}
}
id := profilemanager.ID(switchResp.Id)
cmd.Printf("Profile switched to: %s\n", id.ShortID())
return nil
}
// wrapAmbiguityError turns the daemon's gRPC InvalidArgument errors
// (which carry the resolver's message verbatim) into CLI-friendly text
// that points the user at --show-id.
func wrapAmbiguityError(err error, handle string) error {
if err == nil {View on GitHub (pinned to 93e97f4bf1)
Solutions
- Retry the select once the daemon settles (`netbird status` to verify)
- Check daemon logs for what the switch was doing when Status timed out
- Increase daemon responsiveness (upgrade, reduce log verbosity, check CPU contention)
- If reproducible, report with logs — the switch itself (SwitchProfile) already succeeded; only the status check failed
Defensive patterns
Strategy: retry
Validate before calling
// After a successful SwitchProfile, poll status instead of one 7s-bound call // (illustrative wrapper around the CLI flow) netbird status >/dev/null 2>&1 || sleep 2 # let the daemon settle, then check again
Try / catch
status, err := daemonClient.Status(ctx, &proto.StatusRequest{})
if err != nil {
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
// switch itself succeeded; only the status probe timed out
return fmt.Errorf("profile switched, but status check timed out; verify with `netbird status`")
}
return fmt.Errorf("get service status: %w", err)
} Prevention
- Treat a failed status probe after a successful switch as non-fatal — verify with `netbird status`
- Give the daemon a moment after profile switches before automating follow-ups
- Watch daemon logs when switches consistently time out
When it happens
Trigger: Daemon busy tearing down/bringing up the connection for the new profile and missing the 7s deadline; daemon restarted during the switch; connection to the daemon socket dropped mid-call; management login for the new profile still in flight.
Common situations: Selecting a profile whose management host is slow to contact; low-spec machines where the daemon takes seconds to switch; selecting right after another state-changing command.
Related errors
- call service down method: %w
- connect to service CLI interface: %w
- add profile failed: %w
- WebSocket connection timeout
- %s
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/54bc5dd24d2e8099.
Report an issue: GitHub.