netbirdio/netbird · error
readiness check: unexpected daemon status %q
Error message
readiness check: unexpected daemon status %q
What it means
Thrown by checkReadiness (client/cmd/status.go:286), the handler behind 'netbird status --check ready'. The daemon's StatusResponse carried a status string that matches none of the six known internal.StatusType constants (idle, connecting, connected, needs_login, login_failed, session_expired), so the switch falls into default and the CLI cannot interpret the daemon's state. Almost always means CLI/daemon version skew or an empty status from a daemon that has not initialized its engine yet.
Source
Thrown at client/cmd/status.go:286
return nil
case "ready":
return checkReadiness(resp)
case "startup":
return checkStartup(resp)
default:
return nil
}
}
func checkReadiness(resp *proto.StatusResponse) error {
daemonStatus := internal.StatusType(resp.GetStatus())
switch daemonStatus {
case internal.StatusIdle, internal.StatusConnecting, internal.StatusConnected:
return nil
case internal.StatusNeedsLogin, internal.StatusLoginFailed, internal.StatusSessionExpired:
return fmt.Errorf("readiness check: daemon status is %s", daemonStatus)
default:
return fmt.Errorf("readiness check: unexpected daemon status %q", daemonStatus)
}
}
func checkStartup(resp *proto.StatusResponse) error {
fullStatus := resp.GetFullStatus()
if fullStatus == nil {
return fmt.Errorf("startup check: no full status available")
}
if !fullStatus.GetManagementState().GetConnected() {
return fmt.Errorf("startup check: management not connected")
}
if !fullStatus.GetSignalState().GetConnected() {
return fmt.Errorf("startup check: signal not connected")
}
var relayCount, relaysConnected intView on GitHub (pinned to 93e97f4bf1)
Solutions
- Align CLI and daemon to the same release: reinstall both (e.g. 'netbird service install' with the new binary, then restart the service)
- Retry the check after a few seconds - the daemon sets a real status once the engine initializes
- Inspect the raw value with 'netbird status -A' (or daemon logs) to see exactly what status string was returned
- If you build from source and added a StatusType, extend the switch in checkReadiness to handle it
Example fix
// before
default:
return fmt.Errorf("readiness check: unexpected daemon status %q", daemonStatus)
// after: distinguish not-yet-started from truly unknown
case internal.StatusType(""):
return fmt.Errorf("readiness check: daemon has not reported a status yet")
default:
return fmt.Errorf("readiness check: unexpected daemon status %q (check CLI/daemon version match)", daemonStatus) Defensive patterns
Strategy: validation
Validate before calling
// probe before treating the check result as meaningful
conn, err := DialClientGRPCServer(ctx, daemonAddr)
if err != nil {
// daemon down: not a status problem, fail separately
}
resp, err := proto.NewDaemonServiceClient(conn).Status(ctx, &proto.StatusRequest{})
if err == nil && resp.GetStatus() == "" {
// daemon has not initialized: retry later instead of reading it as 'unexpected'
} Type guard
func isKnownDaemonStatus(s string) bool {
switch internal.StatusType(s) {
case internal.StatusIdle, internal.StatusConnecting, internal.StatusConnected,
internal.StatusNeedsLogin, internal.StatusLoginFailed, internal.StatusSessionExpired:
return true
}
return false
} Prevention
- Keep the CLI and the installed service on the same release version
- In scripts, gate on 'netbird status --check live' before '--check ready'
- Add a small retry/delay around readiness checks instead of treating a single observation as final
When it happens
Trigger: Running 'netbird status --check ready' when resp.GetStatus() returns "" (daemon just started, engine not up) or a new status constant this CLI build does not know (newer daemon binary than CLI, or a custom build that added a StatusType). The switch's default branch fires and formats the raw value with %q.
Common situations: Upgrading the netbird CLI but not the service (or vice versa); systemd/K8s readiness probes firing before the daemon sets its first status; pinned old CLI image against an auto-updated daemon.
Related errors
- startup check: no full status available
- wait for extend session: %v
- switch profile: %v
- switch profile on daemon: %v
- trace failed: %v
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/acace686b82ffed3.
Report an issue: GitHub.