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

  1. Wait for the daemon status to reach Connected before using SSH features that need host-key lookup.
  2. If persistent, run netbird up / login to (re)initialize the client.
  3. 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

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


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