{"record":{"id":"aa971a88afcac11e","repo":"netbirdio/netbird","slug":"interactive-sso-login-failed-v-aa971a","errorCode":null,"errorMessage":"interactive sso login failed: %v","messagePattern":"interactive sso login failed: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/login.go","lineNumber":388,"sourceCode":"}\n\nfunc foregroundLogin(ctx context.Context, cmd *cobra.Command, config *profilemanager.Config, setupKey string, profileID profilemanager.ID) error {\n\tauthClient, err := auth.NewAuth(ctx, config.PrivateKey, config.ManagementURL, config)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create auth client: %v\", err)\n\t}\n\tdefer authClient.Close()\n\n\tneedsLogin, err := authClient.IsLoginRequired(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"check login required: %v\", err)\n\t}\n\n\tjwtToken := \"\"\n\tif setupKey == \"\" && needsLogin {\n\t\ttokenInfo, err := foregroundGetTokenInfo(ctx, cmd, config, profileID)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"interactive sso login failed: %v\", err)\n\t\t}\n\t\tjwtToken = tokenInfo.GetTokenToUse()\n\t}\n\n\terr, _ = authClient.Login(ctx, setupKey, jwtToken)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"login failed: %v\", err)\n\t}\n\n\treturn nil\n}\n\nfunc foregroundGetTokenInfo(ctx context.Context, cmd *cobra.Command, config *profilemanager.Config, profileID profilemanager.ID) (*auth.TokenInfo, error) {\n\thint := \"\"\n\tpm := profilemanager.NewProfileManager()\n\tprofileState, err := pm.GetProfileState(profileID)\n\tif err != nil {\n\t\tlog.Debugf(\"failed to get profile state for login hint: %v\", err)","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/login.go#L370-L406","documentation":"Wraps foregroundGetTokenInfo, the interactive OAuth device-authorization flow run directly by the CLI (not via the daemon): requesting device auth info from management and waiting for the token. It fails when the flow cannot start (see 237: management/IdP side rejects the device-authorize request) or when waiting for the token fails (see 238: code expired, denied, poll error), or when constructing the OAuth flow itself fails.","triggerScenarios":"Management has no IdP/SSO configured so device authorization is unavailable; user never completes or denies the browser consent; device code expires; network interruption during the token poll; clock skew between client and IdP affecting code validity.","commonSituations":"Self-hosted management where OIDC/IdP setup was skipped, but the client attempted interactive login instead of using a setup key; Slow or abandoned browser logins in headless-ish workflows; IdP outage or misconfigured client ID/issuer on management","solutions":["Confirm management actually has an IdP configured for SSO; otherwise log in with a setup key ('netbird up --setup-key <key>')","Rerun the flow and complete the browser approval before the user code expires","Check management and IdP logs for the rejected device-authorization request","Verify system clock sync (timedatectl / w32tm) on both client and servers"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// If the account has no SSO, steer to setup-key login before attempting the flow\nif setupKey == \"\" && !accountHasIdP {\n    return fmt.Errorf(\"no IdP configured; use --setup-key or 'netbird up --setup-key'\")\n}","typeGuard":null,"tryCatchPattern":"tokenInfo, err := foregroundGetTokenInfo(ctx, cmd, config, profileID)\nif err != nil {\n    if strings.Contains(err.Error(), \"device-authorize\") || strings.Contains(err.Error(), \"flow info\") {\n        // start failure: IdP/management side; do not blind-retry\n        return fmt.Errorf(\"interactive sso login failed (check IdP config): %w\", err)\n    }\n    // wait failure: often expiry; a single retry after re-displaying the code is reasonable\n    return fmt.Errorf(\"interactive sso login failed: %w\", err)\n}","preventionTips":["Confirm the management instance has OIDC/SSO configured before choosing interactive login","Keep client clocks synced (NTP) so device codes do not appear expired","For headless or automated hosts, default to setup keys"],"tags":["sso","oauth","device-flow","login","netbird"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}