netbirdio/netbird · error

switch profile on daemon: %v

Error message

switch profile on daemon: %v

What it means

Wraps switchProfile(ctx, handle, username), the helper that dials the daemon and issues the SwitchProfile RPC to resolve a name/ID-prefix into a concrete profile ID. This error fires when the dial itself fails (daemon not running: error 227) or when the RPC returns an error (profile not found for the name+username filter, ambiguous unique-ID prefix: error 228).

Source

Thrown at client/cmd/login.go:257

			return nil, fmt.Errorf("switch profile: %v", err)
		}
	}

	activeProf, err := pm.GetActiveProfile()
	if err != nil {
		return nil, fmt.Errorf("get active profile: %v", err)
	}

	if activeProf == nil {
		return nil, fmt.Errorf("active profile not found, please run 'netbird profile create' first")
	}
	return activeProf, nil
}

func switchProfileOnDaemon(ctx context.Context, pm *profilemanager.ProfileManager, handle string, username string) error {
	resolvedID, err := switchProfile(ctx, handle, username)
	if err != nil {
		return fmt.Errorf("switch profile on daemon: %v", err)
	}

	if err := pm.SwitchProfile(resolvedID); err != nil {
		return fmt.Errorf("switch profile: %v", err)
	}

	conn, err := DialClientGRPCServer(ctx, daemonAddr)
	if err != nil {
		log.Errorf("failed to connect to service CLI interface %v", err)
		return err
	}
	defer conn.Close()

	client := proto.NewDaemonServiceClient(conn)

	status, err := client.Status(ctx, &proto.StatusRequest{})
	if err != nil {
		return fmt.Errorf("unable to get daemon status: %v", err)

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Confirm the daemon is running ('netbird service status', start it if not)
  2. List profiles with 'netbird profile list' and pass the exact name or the full ID (avoid short prefixes)
  3. If names collide across users, also pass the matching --username
  4. Check the inner error text: 'failed to connect to daemon' means daemon-side, 'switch profile failed' means resolution-side
Defensive patterns

Strategy: validation

Validate before calling

// Resolve the handle locally first; only hit the daemon when it exists
profiles, _ := pm.GetProfiles()
for _, p := range profiles {
    if p.Name == handle || strings.HasPrefix(string(p.ID), handle) {
        return nil // resolvable, proceed
    }
}
return fmt.Errorf("profile handle %q unknown; run 'netbird profile list'", handle)

Try / catch

if err := switchProfileOnDaemon(ctx, pm, handle, username); err != nil {
    if status.Code(errors.Unwrap(err)) == codes.NotFound {
        // wrong name or ambiguous prefix: surface profile list to the user
    }
    return err
}

Prevention

When it happens

Trigger: --profile-name value that matches no profile; a short ID prefix that matches several profiles; daemon not installed/started; daemon socket present but stale after an unclean stop.

Common situations: Profile renamed or deleted in another terminal after the user copied its name; Daemon crashed or was stopped as part of troubleshooting; Windows named pipe not available because the service is stopped

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/a267f71213953dd8. Report an issue: GitHub.