Using a data connection with SSH can be a pain, as anyone with a phone and a crippling compulsion to update their VPS’s software on the train ride to town is familiar with. Mosh is a replacement for SSH that attempts to handle the issue of flaky and unstable connections.

The Locale Problem

The locale requested by LANG=en_US.UTF-8 isn't available here.
Running `locale-gen en_US.UTF-8' may be necessary.

mosh-server needs a UTF-8 native locale to run.

Unfortunately, the local environment ([no charset variables]) specifies
the character set "US-ASCII",

The client-supplied environment (LANG=en_US.UTF-8) specifies
the character set "US-ASCII".

locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME=en_GB.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
Connection to <ip> closed.
/usr/bin/mosh: Did not find mosh server startup message. (Have you installed mosh on your server?)

Mosh expects a UTF-8 locale on the server and client. As is evident, the client provides the en_US.UTF-8 locale. Running locale on the server shows an almost identical locale configuration:

LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

Mosh seems to expect LC_ALL to be set to a UTF-8 locale as well as all the rest of the LC_ variables. The manpage for locale1 does not set LC_ALL, and the Archlinux Wiki2 specifies that LC_ALL is not needed:

LC_ALL is the only LC_* variable which cannot be set in locale.conf files: it is meant to be used only for testing or troubleshooting purposes […]

the solution

There’s a myriad of different solutions here.

The easiest is simple, yet not technically proper behaviour - LC_ALL=en_US.UTF-8 mosh <usr@srvr>. Another possible solution, recommended by people on the Github issue page is to just add the flag --server="LANG=$LANG mosh-server" to the mosh command.

However, both of these would require aliasing in your .bashrc or .zshrc or .whateverrc, and my .rc’s are rapidly filling with aliases and I’m not desperate to add more. So let’s try to resolve this the “proper” way.

Exporting locales across SSH

Thankfully, SSH includes a method to push locales from the client to the server.

Edit /etc/ssh/sshd_config with your favourite $EDITOR and make this change:

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

On the client, edit your $HOME/.ssh/config and add the line

SendEnv LANG LC_ALL

and et voilá, running mosh <usr@srvr> automagickally works.


  1. locale(1) manpage ↩︎

  2. Arch Wiki - Locale ↩︎