How to kill a frozen SSH session: escape sequences

Press Enter, then ~, then . to close a frozen SSH session. Your local ssh handles these keys, so it works even when the server no longer answers. The Enter matters, because the escape character is only recognized right after a new line. ssh then exits with code 255.

Updated . OpenSSH 10.3 on macOS to OpenSSH 10.0 on Debian 13 in a throwaway container, with keys sent through a terminal from a script.

Close a frozen session

Enter  ~  .

You will see:

Connection to server closed.

We paused the server so it answered nothing, and then typed ~. straight after other text. Nothing happened. After Enter, ~. closed the session at once. If it seems to do nothing, press Enter and try again.

With multiplexing, ~. in a session that reuses the connection closes only that session. In the session that opened the connection, without ControlPersist, it ends every session that shares it.

Closing the session also ends the programs in it. A shell in tmux keeps running on the server: see how to keep an SSH session alive after disconnect with tmux.

All the escape sequences

Type ~? after a new line and your ssh prints this list. All of them need a new line first, and they are not sent to the server.

KeysWhat it does
~.Closes the connection
~^ZSuspends ssh, where ^Z means Ctrl+Z. Return with fg
~#Lists open channels and forwards
~&Puts ssh in the background when it waits for forwards to end at logout
~?Shows the list
~COpens a small command line, if enabled
~BSends a BREAK
~IShows connection information, in versions after 10.0
~RAsks for a new session key
~V and ~vDecrease and increase log detail
~~Sends one ~

Suspend with ~^Z

~^Z [suspend ssh]
[1]+  Stopped                 ssh server
$ fg

This gets you back to your local shell without closing the session. After fg the session continued normally in our test.

~C: add a forward to an open session

Since OpenSSH 9.2 this is off by default, and ~C prints commandline disabled. To turn it on:

ssh -o EnableEscapeCommandline=yes server

Or set EnableEscapeCommandline yes in ~/.ssh/config. Then ~C opens an ssh> prompt:

ssh> -L 8022:localhost:22
Forwarding port.
ssh> -KL8022
Canceled forwarding.

Type ? at that prompt for the commands. It also accepts -R and -D. We confirmed that the port opened after -L and closed after -KL.

What -L, -R and -D do is covered in SSH tunnels explained: local, remote and dynamic.

Nested sessions

If you SSH from one server to another, the outermost ssh sees the escape first. Each extra ~ passes it one level down:

KeysCloses
~.The first connection, which also ends the inner one
~~.The second connection, leaving you on the first server
~~~.The third connection, following the same rule

We tested the first two. ~~. printed Connection to localhost closed. and left the outer session working.

Change or disable the escape character

Pick another character if ~ is awkward on your keyboard:

ssh -e '^' server

Now ^. closes the session, and ~. is ordinary text. To turn escapes off, for example when binary data passes through the session:

ssh -e none server

In ~/.ssh/config, the option is:

Host server
  EscapeChar none

With none, the session can no longer be closed from the keyboard when it freezes. Set ServerAliveInterval so that a dead connection ends by itself. See Broken pipe and keepalive.

Questions

Why does my SSH session freeze?

Usually the network dropped while the session was quiet, and ssh is still waiting for a server it can no longer reach. Close it with Enter, ~, . and set ServerAliveInterval 30 in ~/.ssh/config: ssh then notices a dead connection and exits by itself after about a minute and a half.

Why does ~. not close my SSH session?

The escape character only works right after a new line, so press Enter first. It also does nothing when EscapeChar is set to none, when -e chose another character, or in a session without a terminal.

How do I type a ~ at the start of a line over SSH?

Type it twice. ~~ sends a single ~ to the server.

What does ~C do in SSH?

It opens an ssh> prompt where you add or cancel port forwards in a running session. Since OpenSSH 9.2 it is off until you set EnableEscapeCommandline yes.

Sources

More in Sessions and tmux

All guides