Check if ssh.Client connection is alive

Hi golangbride community, I have a simple ssh client in go and I’m trying to detect when an active ssh.Client loses its connection to the ssh server.

Here is a minimal example:

func main() {
    quit := make(chan bool)

    config := &ssh.ClientConfig{
        User: "user",
        Auth: []ssh.AuthMethod{

    client, err := ssh.Dial("tcp", "localhost:22", config)
    if err != nil {

    go func() {
        // check if connection is still alive

        // client.Wait() does not return if the network of the 
        // client is down or if the server is turned of
        err := client.Wait()
        if err != nil {
        quit <- true


I also tried to create and close new sessions periodicly on the client with:

for {
    sess, err := client.NewSession()
    defer sess.Close()
    time.Sleep(5 * time.Second)

But if the network is down client.NewSession() blocks endlessly.

Is there a reliable way to detect connection loss on an open ssh.Client ?

A long time ago I monkey patched the ssh package with this for the purpose:

package ssh

func (c *ClientConn) CheckServerAlive() error {
        _, err := c.sendGlobalRequest(globalRequestMsg{"", true})

        if err == nil || err.Error() == "request failed" {
                // Any response is a success.
                return nil

        return err

The package has evolved a bit since then so maybe that doesn’t fit as is, but the concept should be the same.

The unusual error handling is because a server that does not support keepalives may result in that error, but they are still alive. I’m sure it could be made more robust, this was years ago when I was writing my first lines of Go. :wink:

(Also, your sessions from the second loop above don’t get closed, as defer only runs as the function exits. Otherwise you could probably still do that, but combine with a timeout.)

1 Like

Hello and thank you calmh, but unfortunately the go ssh package seems to have changed since your solution. CientConn is no more and if possible i need a working solution without touching the ssh package.

I tried send a request via ssh.Client.Conn.sendRequest() but this also blocks endlessly if the network goes down.

Run it in a goroutine and time it out?

1 Like

I did that and it works. Thanks again calmh. I somehow thought that this is a common problem and should be part the ssh package itself.

The general approach, not just with the ssh package, is the best way to tell if a connection is alive is to use it. If you do some kind of probe, then use the connection, an unknown amount of time has passed between those two operations, so the previous value may be out of date.

Yeah. The reason for my keepalives above was mostly to keep the connection alive through NAT boxes when it wasn’t being used, as the usage was for tunneling that may or may not be in use from time to time.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.