netbirdio/netbird · error
failed to get log level: %v
Error message
failed to get log level: %v
What it means
Raised by runForDuration (`netbird debug for <duration>`) when client.GetLogLevel fails after Status already succeeded. The command reads the daemon's current log level so it can force TRACE and later restore the original value. The gRPC status message is surfaced verbatim.
Source
Thrown at client/cmd/debug.go:264
}
defer func() {
if err := conn.Close(); err != nil {
log.Errorf(errCloseConnection, err)
}
}()
client := proto.NewDaemonServiceClient(conn)
stat, err := client.Status(cmd.Context(), &proto.StatusRequest{ShouldRunProbes: true})
if err != nil {
return fmt.Errorf("failed to get status: %v", status.Convert(err).Message())
}
stateWasDown := stat.Status != string(internal.StatusConnected) && stat.Status != string(internal.StatusConnecting)
initialLogLevel, err := client.GetLogLevel(cmd.Context(), &proto.GetLogLevelRequest{})
if err != nil {
return fmt.Errorf("failed to get log level: %v", status.Convert(err).Message())
}
if stateWasDown {
if _, err := client.Up(cmd.Context(), &proto.UpRequest{}); err != nil {
cmd.PrintErrf("Failed to bring service up: %v\n", status.Convert(err).Message())
} else {
cmd.Println("netbird up")
time.Sleep(time.Second * 10)
}
}
initialLevelTrace := initialLogLevel.GetLevel() >= proto.LogLevel_TRACE
if !initialLevelTrace {
_, err = client.SetLogLevel(cmd.Context(), &proto.SetLogLevelRequest{
Level: proto.LogLevel_TRACE,
})
if err != nil {
return fmt.Errorf("failed to set log level to TRACE: %v", status.Convert(err).Message())View on GitHub (pinned to 93e97f4bf1)
Solutions
- Compare versions: `netbird version` for the CLI versus the daemon version shown by `netbird status`; upgrade whichever is older so both come from the same release
- Restart the netbird service and re-run the debug command
- If versions match and it persists, check the daemon log at the timestamp of the failure for the rejected RPC
Defensive patterns
Strategy: try-catch
Validate before calling
# ensure daemon version supports the log-level RPCs before running the command netbird status | grep -q 'Daemon version' && netbird version # compare the two; upgrade if the daemon is older
Try / catch
resp, err := client.GetLogLevel(ctx, &proto.GetLogLevelRequest{})
if err != nil {
switch status.Code(err) {
case codes.Unimplemented:
// version skew: daemon predates this RPC; upgrade the service
return fmt.Errorf("daemon too old for GetLogLevel: upgrade the netbird service: %v", err)
case codes.Unavailable, codes.Canceled:
// daemon down or command interrupted; restart and retry once
return fmt.Errorf("daemon unavailable, restart it and retry: %w", err)
default:
return err
}
} Prevention
- Upgrade the netbird service whenever you upgrade the CLI so daemon RPCs match the CLI's calls
- Restart the daemon before long debug sessions to avoid mid-command restarts
- Treat Unimplemented from a daemon RPC as a version signal first, not a bug
When it happens
Trigger: The daemon binary predates the GetLogLevel RPC and returns Unimplemented; the daemon restarts or shuts down between the Status and GetLogLevel calls; the context is canceled mid-sequence; the daemon is in a half-initialized state where the handler is not yet registered.
Common situations: CLI/daemon version skew after a partial upgrade (new CLI package, old service still running); running a built-from-source CLI against a released daemon; the service being restarted by a supervisor mid-command.
Related errors
- failed to set log level to TRACE: %v
- failed to get status: %v
- failed to set sync response persistence: %v
- connect to daemon: %w
- expose service: %v
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/8881ed6e5ad89764.
Report an issue: GitHub.