netbirdio/netbird · error
client not initialized
Error message
client not initialized
What it means
Returned by the daemon's GetPeerSSHHostKey RPC handler (client/server/server.go:1630) when s.connectClient is nil. The connect client is created when the daemon establishes its session (login/up); nil means the daemon is not initialized (no session), so there is no engine to query for peer SSH host keys.
Source
Thrown at client/server/server.go:1630
return sshServerState
}
// GetPeerSSHHostKey retrieves SSH host key for a specific peer
func (s *Server) GetPeerSSHHostKey(
ctx context.Context,
req *proto.GetPeerSSHHostKeyRequest,
) (*proto.GetPeerSSHHostKeyResponse, error) {
if ctx.Err() != nil {
return nil, ctx.Err()
}
s.mutex.Lock()
connectClient := s.connectClient
statusRecorder := s.statusRecorder
s.mutex.Unlock()
if connectClient == nil {
return nil, errors.New("client not initialized")
}
engine := connectClient.Engine()
if engine == nil {
return nil, errors.New("engine not started")
}
peerAddress := req.GetPeerAddress()
hostKey, found := engine.GetPeerSSHKey(peerAddress)
response := &proto.GetPeerSSHHostKeyResponse{
Found: found,
}
if !found {
return response, nil
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Wait for the daemon status to reach Connected before using SSH features that need host-key lookup.
- If persistent, run netbird up / login to (re)initialize the client.
- Callers (e.g. the SSH ProxyCommand) should degrade gracefully: prompt the user instead of failing hard.
Example fix
// before
resp, err := daemonClient.GetPeerSSHHostKey(ctx, req)
if err != nil { exit(1) } // "client not initialized" at boot
// after: gate on session state
status, _ := daemonClient.Status(ctx)
if status.GetStatus() != daemonpb.StatusEnum_CONNECTED {
return fmt.Errorf("daemon not connected yet; retry SSH later")
}
resp, err := daemonClient.GetPeerSSHHostKey(ctx, req) Defensive patterns
Strategy: validation
Validate before calling
// Require a connected daemon before any SSH host-key lookup.
status, err := daemonClient.Status(ctx)
if err != nil {
return err
}
if status.GetStatus() != daemonpb.StatusEnum_CONNECTED {
return fmt.Errorf("daemon has no session (status %s); run up/login first", status.GetStatus())
} Try / catch
resp, err := daemonClient.GetPeerSSHHostKey(ctx, req)
if err != nil {
if strings.Contains(err.Error(), "client not initialized") {
// daemon not logged in: prompt user to connect, then retry
}
return err
} Prevention
- SSH helpers invoked from ssh_config should tolerate a not-yet-initialized daemon.
- In boot-time scripts, wait for the daemon socket plus Connected status before SSH use.
When it happens
Trigger: Calling GetPeerSSHHostKey on a daemon that has not logged in / connected yet, or after logout tore the connect client down; a UI restart racing the first connect.
Common situations: SSH config helper (netbird's ssh shim) invoked before netbird up completes; scripts calling the daemon gRPC socket directly at boot; running the SSH command after logout.
Related errors
- engine not started
- service is not up
- management client is not initialised
- peer has no stored SSH host key
- create SSH proxy: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/c4bc264a25617be2.
Report an issue: GitHub.