netbirdio/netbird · error

client not started

Error message

client not started

What it means

Same call site as index 6 (middleware.go:472) but for the errValidationUnavailable branch: 502 'authentication service unavailable'. validateSessionToken wraps this sentinel (middleware.go:698) when an OIDC method token must be checked via the sessionValidator gRPC client (ValidateSession on management) and that RPC itself errors.

Source

Thrown at client/embed/embed.go:33

	wgdevice "golang.zx2c4.com/wireguard/device"
	wgnetstack "golang.zx2c4.com/wireguard/tun/netstack"

	"github.com/netbirdio/netbird/client/iface"
	"github.com/netbirdio/netbird/client/iface/netstack"
	"github.com/netbirdio/netbird/client/internal"
	"github.com/netbirdio/netbird/client/internal/auth"
	"github.com/netbirdio/netbird/client/internal/peer"
	"github.com/netbirdio/netbird/client/internal/profilemanager"
	sshcommon "github.com/netbirdio/netbird/client/ssh"
	"github.com/netbirdio/netbird/client/system"
	"github.com/netbirdio/netbird/shared/management/domain"
	mgmProto "github.com/netbirdio/netbird/shared/management/proto"
	"github.com/netbirdio/netbird/util/capture"
)

var (
	ErrClientAlreadyStarted = errors.New("client already started")
	ErrClientNotStarted     = errors.New("client not started")
	ErrEngineNotStarted     = errors.New("engine not started")
	ErrConfigNotInitialized = errors.New("config not initialized")
)

const (
	// PeerStatusConnected indicates the peer is in connected state.
	PeerStatusConnected = peer.StatusConnected
)

// PeerConnStatus is a peer's connection status.
type PeerConnStatus = peer.ConnStatus

// Client manages a netbird embedded client instance.
type Client struct {
	deviceName string
	config     *profilemanager.Config
	mu         sync.Mutex
	cancel     context.CancelFunc

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Check management health and connectivity from the proxy host (the gRPC endpoint the sessionValidator dials).
  2. Look at proxy logs: the underlying error is chained after 'session validation unavailable', naming dial timeout, TLS, or unavailable status.
  3. Restart or re-dial the gRPC connection / proxy process if the channel is wedged after a management restart.
  4. Verify mTLS material between proxy and management is current on both sides.
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight the proxy->management validation path before relying on it.
conn, err := grpc.NewClient(mgmtAddr, creds)
if err != nil {
    return fmt.Errorf("management dial: %w", err)
}
defer conn.Close()
c := healthpb.NewHealthClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
if _, err := c.Check(ctx, &healthpb.HealthCheckRequest{}); err != nil {
    return fmt.Errorf("management unhealthy: %w", err)
}

Try / catch

// With retry (502 means the backend, not the credentials, failed):
var resp *http.Response
for attempt := 0; attempt < 3; attempt++ {
    resp, err = client.Do(req.Clone(ctx))
    if err == nil && resp.StatusCode != http.StatusBadGateway {
        break
    }
    time.Sleep(time.Duration(1<<attempt) * time.Second) // backoff; mgmt may be restarting
}

Prevention

When it happens

Trigger: Request presents a header token for a domain whose scheme is OIDC, mw.sessionValidator is wired, and the gRPC call to management's ValidateSession fails: management down or restarting, gRPC connection refused/timeout, TLS handshake failure between proxy and management, or management returning an error status.

Common situations: Management service restarted and the proxy's gRPC connection has not recovered; mTLS/cert mismatch between proxy and management after certificate renewal; management pod evicted or crashing; network policy blocking the proxy-to-management port.

Related errors


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