I'm working on an rsync-based backup for a FreeNAS system.

Part of the backup process involves logging into the remote system that serves as the backup storage. Whenever I do that, I get the message

Could not create directory '/root/.ssh'.

I'm assuming this is due to the fact that /root is read-only, because when I try to create ~/.ssh manually, I receive:

mkdir: /root/.ssh: Read-only file system

Because of this, I have already moved the known_hosts file more appropriate for my backup process and am using -o UserKnownHostsFile to resolve any issues related to that.

However, ssh still tries to create the ~/.ssh folder when I invoke it. How can I get it to not try to create the folder?

  • Does it just normally operate with /root read-only? In other words, could you briefly mount it read-write to make changes once and have it normally be read-only?
    – kurtm
    Commented Oct 25, 2013 at 19:05
  • @kurtm: This seems to be the default. Actually / is mounted read-only. Commented Oct 25, 2013 at 19:38
  • Okay. So you could mount it read-write, but it's not usually.
    – kurtm
    Commented Oct 25, 2013 at 19:56

2 Answers 2


The solution mentioned here is good, but I was looking for one which didn't require ~/.ssh to be present or required an attempt for it to be created (running on Windows, distributing a MSYS built ssh.exe, but running on other machines without MSYS/Cygwin installed).

Unfortunately, it appears the routine is hardcoded in the source code, regardless of what value you give to UserKnownHostsFile:

    r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
        strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
    if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) {
        if (mkdir(buf, 0700) < 0)
            error("Could not create directory '%.200s'.",

However, it's interesting to note that it attempts to expand the $HOME environment variable to determine the home directory. Since the buffer is around 256 bytes, we can actually bypass the if condition by overflowing the buffer (defining HOME to a string longer than 256 bytes), e.g.:

export HOME=$HOME/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././.
  • Wouldn't it be easier to set $HOME to /tmp or some place where you can write?
    – muru
    Commented Jun 9, 2017 at 5:34
  • Windows doesn't have /tmp unfortunately, or rather, I don't know what it maps to (if it does at all). %tmp% is the Windows equivalent, however it needs to be converted to a MSYS-like path for it to work (eg /c/Windows/temp instead of C:\Windows\temp), which is a major pain to do in a batch file. Ideally though, I don't want it creating directories at all.
    – zinga
    Commented Jun 9, 2017 at 6:18

Remount the root filesystem read-write temporarily and make a symbolic link for .ssh that points somewhere where ssh can write. This way you can also do things like add ssh keys in the future, or allow new known_hosts without having to go to extra strenuous steps. And you could get rid of your -o UserKnownHostsFile option at the same time.

  • 1
    +1 simple and effective. Side note another approach in the same vein is just changing the user's defined location for their home directory to be an rw mounted space. Commented Oct 25, 2013 at 20:03
  • Your suggestion is probably the way to go. For some reason I assumed that /root might be recreated from other data at each reboot, but I never actually verified that. I'll verify this and get back to you :) Commented Oct 26, 2013 at 0:57
  • +oliversalzburg That would blow a hole in my idea. But you could work around that if you find out where it is re-creating /root from and changing the original.
    – kurtm
    Commented Oct 26, 2013 at 1:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .