netbirdio/netbird · error
interactive sso login failed: %v
Error message
interactive sso login failed: %v
What it means
In Android interactive login, when IsLoginRequired returns true, foregroundGetTokenInfo runs the SSO flow: it obtains a session/code request from management, opens the browser via the injected URLOpener, and exchanges the result for a user JWT. Any failure in that chain (user cancels, opener error, exchange timeout, IdP unavailable, Android TV flow issues) is wrapped here with %v.
Source
Thrown at client/android/login.go:170
func (a *Auth) login(urlOpener URLOpener, isAndroidTV bool) error {
authClient, err := auth.NewAuth(a.ctx, a.config.PrivateKey, a.config.ManagementURL, a.config)
if err != nil {
return fmt.Errorf("failed to create auth client: %v", err)
}
defer authClient.Close()
// check if we need to generate JWT token
needsLogin, err := authClient.IsLoginRequired(a.ctx)
if err != nil {
return fmt.Errorf("failed to check login requirement: %v", err)
}
jwtToken := ""
email := ""
if needsLogin {
tokenInfo, err := a.foregroundGetTokenInfo(authClient, urlOpener, isAndroidTV)
if err != nil {
return fmt.Errorf("interactive sso login failed: %v", err)
}
jwtToken = tokenInfo.GetTokenToUse()
email = tokenInfo.Email
}
err, _ = authClient.Login(a.ctx, "", jwtToken)
if err != nil {
return fmt.Errorf("login failed: %v", err)
}
// Stored after Login, not before: a rejected token must not leave a hint
// pointing at an account that cannot be used.
if email != "" && a.cfgPath != "" {
if err := writeProfileEmail(a.cfgPath, email); err != nil {
log.Warnf("failed to store profile account email: %v", err)
}
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Retry the flow: many failures are user cancellation or transient IdP issues.
- Verify the URLOpener works on the target device (register the redirect scheme/intent filter on Android).
- Check management and IdP configuration (redirect URI, client ID) if the failure is repeatable at the same step.
Defensive patterns
Strategy: try-catch
Type guard
func isInteractiveSSOFailure(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "interactive sso login failed:")
} Try / catch
err := a.login(urlOpener, isAndroidTV)
if err != nil && isInteractiveSSOFailure(err) {
// covers user cancellation, opener failure, token exchange timeout:
// offer a retry; if it always fails at the same step, check redirect/
// intent-filter registration and IdP configuration
} Prevention
- Register the SSO redirect scheme (intent filter/deep link) in the app manifest.
- Test the URLOpener on every form factor, especially Android TV where browsers are scarce.
- Complete the browser flow promptly; long delays can expire the token exchange request.
When it happens
Trigger: User closing the browser or canceling before completing SSO; URLOpener implementation failing (especially on Android TV); token exchange request expiring; IdP outage or misconfigured redirect.
Common situations: Deep-link/custom-scheme redirect not registered for the app; TV devices where no browser is available; clock skew or expired flow state in the token exchange.
Related errors
- interactive sso login failed: %v
- failed to check SSO support: %v
- login failed: %v
- failed to check login requirement: %v
- interactive sso login failed: %v
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/11449bccad199432.
Report an issue: GitHub.