netbirdio/netbird · error

waiting sso login failed with: %v

Error message

waiting sso login failed with: %v

What it means

handleSSOLogin's WaitSSOLogin long-poll RPC to the daemon failed. The daemon blocks waiting for the IdP callback after the user opens the verification URI; this error appears when the CLI's context is cancelled (Ctrl+C), the daemon-side wait times out or expires, the daemon loses its connection to management mid-wait, or the gRPC transport drops.

Source

Thrown at client/cmd/login.go:357

	if err := server.RestoreResidualState(ctx, profilemanager.NewServiceManager(configFilePath).GetStatePath()); err != nil {
		log.Warnf("failed to restore residual state: %v", err)
	}
	nbnet.Init()

	err = foregroundLogin(ctx, cmd, config, setupKey, activeProf.ID)
	if err != nil {
		return fmt.Errorf("foreground login failed: %v", err)
	}
	cmd.Println("Logging successfully")
	return nil
}

func handleSSOLogin(ctx context.Context, cmd *cobra.Command, loginResp *proto.LoginResponse, client proto.DaemonServiceClient, pm *profilemanager.ProfileManager) error {
	openURL(cmd, loginResp.VerificationURIComplete, loginResp.UserCode, noBrowser, showQR)

	resp, err := client.WaitSSOLogin(ctx, &proto.WaitSSOLoginRequest{UserCode: loginResp.UserCode, Hostname: hostName})
	if err != nil {
		return fmt.Errorf("waiting sso login failed with: %v", err)
	}

	if resp.Email != "" {
		err = pm.SetActiveProfileState(&profilemanager.ProfileState{
			Email: resp.Email,
		})
		if err != nil {
			log.Warnf("failed to set active profile email: %v", err)
		}
	}

	return nil
}

func foregroundLogin(ctx context.Context, cmd *cobra.Command, config *profilemanager.Config, setupKey string, profileID profilemanager.ID) error {
	authClient, err := auth.NewAuth(ctx, config.PrivateKey, config.ManagementURL, config)
	if err != nil {
		return fmt.Errorf("failed to create auth client: %v", err)

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Rerun 'netbird login' and complete the browser step promptly (mind the code expiry window)
  2. Ensure the daemon stays up during the flow (netbird service status) and check its logs
  3. Verify daemon-to-management connectivity and IdP health
  4. If aborting intentionally, Ctrl+C early rather than letting the code expire confusingly
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm the daemon connection is alive before entering the long wait
if _, err := client.Status(ctx, &proto.StatusRequest{}); err != nil {
    return fmt.Errorf("daemon unavailable before SSO wait: %w", err)
}

Try / catch

resp, err := client.WaitSSOLogin(ctx, &proto.WaitSSOLoginRequest{...})
if err != nil {
    if ctx.Err() != nil {
        return fmt.Errorf("sso wait canceled: %w", err)
    }
    return fmt.Errorf("waiting sso login failed with: %w", err)
}

Prevention

When it happens

Trigger: User aborts the command before completing browser auth; device/user code expires before approval; daemon restarted or crashed during the wait; management connection lost; ctx deadline exceeded on the CLI side.

Common situations: Browser auth left unfinished in a remote SSH session; IdP slow or down (SAML/OIDC latency) so the code expires; Daemon crash-looping or being upgraded mid-login

Related errors


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