netbirdio/netbird · error

getting device authorization flow info failed with error: %v

Error message

getting device authorization flow info failed with error: %v

What it means

Returned by authenticateWithDeviceCodeFlow when the getDeviceFlow RPC fails with any gRPC error other than NotFound or Unimplemented (client/internal/auth/oauth.go:125-126). This is the catch-all branch: transport failures, DeadlineExceeded, PermissionDenied, Internal, or Unavailable from management. The underlying gstatus text is embedded via %v, so the wrapped code and message are the real diagnostic.

Source

Thrown at client/internal/auth/oauth.go:126

func authenticateWithDeviceCodeFlow(ctx context.Context, config *profilemanager.Config, hint string) (OAuthFlow, error) {
	authClient, err := NewAuth(ctx, config.PrivateKey, config.ManagementURL, config)
	if err != nil {
		return nil, fmt.Errorf("failed to create auth client: %v", err)
	}
	defer authClient.Close()

	deviceFlowInfo, err := authClient.getDeviceFlow(authClient.client)
	if err != nil {
		switch s, ok := gstatus.FromError(err); {
		case ok && s.Code() == codes.NotFound:
			return nil, fmt.Errorf("no SSO provider returned from management. " +
				"Please proceed with setting up this device using setup keys " +
				"https://docs.netbird.io/how-to/register-machines-using-setup-keys")
		case ok && s.Code() == codes.Unimplemented:
			return nil, fmt.Errorf("the management server, %s, does not support SSO providers, "+
				"please update your server or use Setup Keys to login", config.ManagementURL)
		default:
			return nil, fmt.Errorf("getting device authorization flow info failed with error: %v", err)
		}
	}

	if hint != "" {
		deviceFlowInfo.SetLoginHint(hint)
	}

	return deviceFlowInfo, nil
}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Read the embedded gRPC code in the message (e.g. 'rpc error: code = Unavailable') to pick the right track
  2. Check management server health and logs at the timestamp of the login attempt
  3. Retry netbird up - Unavailable/DeadlineExceeded are often transient during management restarts
  4. If Unauthenticated, re-register the host (setup key) since the stored credentials are no longer accepted
Defensive patterns

Strategy: try-catch

Type guard

// Narrow the catch-all branch by extracting the gRPC code
func isTransientGRPC(err error) bool {
	s, ok := gstatus.FromError(err)
	if !ok {
		return false
	}
	return s.Code() == codes.Unavailable || s.Code() == codes.DeadlineExceeded
}

Try / catch

if err != nil {
	if s, ok := gstatus.FromError(errors.Unwrap(err)); ok {
		switch s.Code() {
		case codes.Unavailable, codes.DeadlineExceeded:
			// transient: retry the login flow
		case codes.Unauthenticated:
			// host key session rejected: re-register with a setup key
		default:
			// management-side error: check server logs
		}
	}
}

Prevention

When it happens

Trigger: Connection dropped mid-RPC (Unavailable), management handler panic or DB error (Internal), auth token expired for the host key session (Unauthenticated), or request timeout (DeadlineExceeded) while management fetches IdP configuration.

Common situations: Management server crash-looping or restarting; management database unreachable so the IdP lookup errors; load balancer idle-timeouting the gRPC stream; host key session expired after long offline periods.

Related errors


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