netbirdio/netbird · error
engine is not running
Error message
engine is not running
What it means
extendAuthSession starts from an auth snapshot of the running client; when authSnapshot returns nil config or nil connect-client, the engine was never started or has been stopped (for example after logout), so there is no live session to extend. This is a precondition failure about client lifecycle, not a network or IdP problem.
Source
Thrown at client/android/session.go:283
}
ctx, cancel := context.WithCancel(context.Background())
c.extendCancel = cancel
return ctx, nil
}
func (c *Client) endExtend() {
c.extendMu.Lock()
defer c.extendMu.Unlock()
if c.extendCancel != nil {
c.extendCancel()
c.extendCancel = nil
}
}
func (c *Client) extendAuthSession(ctx context.Context, urlOpener URLOpener, isAndroidTV bool) error {
cfg, cfgPath, cc := c.authSnapshot()
if cfg == nil || cc == nil {
return fmt.Errorf("engine is not running")
}
engine := cc.Engine()
if engine == nil {
return fmt.Errorf("engine is not initialized")
}
authClient, err := auth.NewAuth(ctx, cfg.PrivateKey, cfg.ManagementURL, cfg)
if err != nil {
return fmt.Errorf("failed to create auth client: %v", err)
}
defer authClient.Close()
// Passing the config path makes the flow pick up the login_hint: an extend
// renews the session of the account already signed in, so it must not stop to
// offer a choice.
a := NewAuthWithConfig(ctx, cfg, cfgPath)
tokenInfo, err := a.foregroundGetTokenInfo(authClient, urlOpener, isAndroidTV)
if err != nil {View on GitHub (pinned to 93e97f4bf1)
Solutions
- Only enable session renewal when the client is running and connected — Status() is neither Idle nor NeedsLogin
- After a logout or stop, require a full interactive login instead of extend
- If it races startup, wait for the connected state before invoking
Example fix
// before
client.ExtendAuthSession(opener, false, listener) // called regardless of client state
// after: gate on the run-loop status
if s := client.Status(); s != "Idle" && s != "NeedsLogin" {
client.ExtendAuthSession(opener, false, listener)
} Defensive patterns
Strategy: validation
Validate before calling
// Gate the renew action on the run-loop status before calling
String s = client.Status();
if (!"Idle".equals(s) && !"NeedsLogin".equals(s)) {
client.ExtendAuthSession(opener, isTV, listener);
} Type guard
fun canExtendSession(status: String): Boolean = status != "Idle" && status != "NeedsLogin"
Try / catch
// In the ErrListener of ExtendAuthSession
func (l *extendListener) OnError(err error) {
if strings.Contains(err.Error(), "engine is not running") {
// precondition failure: start/connect the client, or offer a full login instead
return
}
l.show(err)
} Prevention
- Enable session-renewal UI only when Status() shows a connected client
- After logout or engine stop, route the user to a full login, not extend
- Avoid racing startup: wait for the connect loop to report before showing renew controls
When it happens
Trigger: ExtendAuthSession called before the client has started and connected (Status is Idle), after the engine was stopped, or after logout cleared the session — the snapshot has no cfg/cc to renew even though the session deadline may still be displayed.
Common situations: UI offering session renewal from a cached deadline after the tunnel went down, racing app startup before the connect loop is up, renew dialog still visible after the user logged out.
Related errors
- engine is not running
- session extend already in progress
- engine is not initialized
- management client is not initialised
- service is not up
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/df4bbea6b2909ad1.
Report an issue: GitHub.