SSH remote environment: binary upload always fails with ENOENT on Synology DSM (internal-sftp virtual root ≠ shell-resolved $HOME)

Status Open
Maintainer reply None cached
Activity 1 comment · opened Jul 17, 2026

Summary

When setting up an SSH remote environment against a Synology NAS (DSM), the initial server-binary deployment fails 100% of the time with:

Couldn't upload to the remote (server binary): a required file or directory is missing [ENOENT]

Root cause: Desktop resolves the remote home directory via a shell probe (echo $HOME, from /etc/passwd), which returns the real filesystem path (e.g. /var/services/homes/<user>). It then reuses that same absolute path for the SFTP upload of the server binary. On Synology DSM, the internal-sftp subsystem presents its own virtual root that is independent of the real filesystem and of sshd_config's ChrootDirectory setting — it only exposes DSM's defined shared folders (e.g. data, docker, home, homes, roms), and does not include /var at all. Any SFTP write targeting /var/services/homes/<user>/... therefore fails with ENOENT, regardless of permissions, ACLs, or disk space — because that path simply does not exist inside the SFTP session's namespace, even though it exists (and is fully writable) in the real filesystem.

This is likely to affect any environment where the SFTP subsystem's visible root differs from the real filesystem root reachable via a plain shell exec (Synology DSM confirmed; likely other NAS/hardened-SSH-jail setups too).

Environment

  • Claude Desktop (macOS), SSH remote environment feature
  • Target: Synology DSM (x86_64, Geminilake-based model), kernel 4.4.302
  • Remote OpenSSH: ChrootDirectory none, Subsystem sftp internal-sftp -f DAEMON -u 000
  • Remote user shell: /bin/sh (BusyBox ash)
  • User home per /etc/passwd: /var/services/homes/<user>

Reproduction

  1. Add an SSH remote environment in Claude Desktop pointing at a Synology DSM NAS, using a normal (non-admin) DSM user account.
  2. Attempt to connect / send a message to trigger remote server setup.
  3. Observe the connection fails every time with the ENOENT error above.

Evidence

From ~/Library/Logs/Claude/ssh.log:

[BinaryDeployment] Remote: home=/var/services/homes/<user>, platform=linux-amd64, shell=posix, localVer=<hash>
[BinaryDeployment] Deploying server binary linux-amd64 to /var/services/homes/<user>/.claude/remote/srv/<hash> (remote=missing, local=<hash>)
[BinaryDeployment] SFTP upload failed (/var/services/homes/<user>/.claude/remote/srv/<hash>/server): No such file
[RemoteServerController] Connection failed (...): Couldn't upload to the remote (server binary): a required file or directory is missing [ENOENT]

Manually reproduced with plain sftp:

$ sftp <user>@host
sftp> put /tmp/testserver /var/services/homes/<user>/.claude/remote/srv/<hash>/server
dest open "/var/services/homes/<user>/.claude/remote/srv/<hash>/server": No such file or directory

...even though the target directory demonstrably exists, is owned by the connecting user, and has 700 permissions (verified over a normal SSH exec channel: ls -la /var/services/homes/<user>/.claude/remote/srv/<hash>/ succeeds and shows the directory).

Listing the SFTP session's own root confirms the virtual-filesystem mismatch:

sftp> pwd
Remote working directory: /
sftp> ls -la
drwxrwxr-x    1 docker   users    50 ...  data
drwxr-xr-x    1 docker   users    26 ...  docker
drwxrwxrwx    1 <user>   users   122 ...  home
drwxrwxrwx    1 root     root     40 ...  homes
drwxrwxrwx    1 root     root    124 ...  roms

No /var entry exists in this listing at all. However, the identical underlying directory is reachable over SFTP via the path DSM exposes for it:

sftp> put /tmp/testserver homes/<user>/.claude/remote/srv/<hash>/server
Uploading /tmp/testserver to /homes/<user>/.claude/remote/srv/<hash>/server

— which succeeds, and the uploaded file is immediately visible at the real path /var/services/homes/<user>/.claude/remote/srv/<hash>/server via a normal SSH exec ls. So the file transfer, permissions, and target directory are all fine — only the specific absolute path Desktop chooses for the SFTP operation is invalid within the SFTP subsystem's namespace.

Also confirmed /homes and /home do not exist at all as real paths outside of the internal-sftp session (ls /homes over a normal SSH exec returns "No such file or directory") — so this isn't a symlink Desktop could just follow; the two namespaces are genuinely distinct on this system, and there is no single home-directory value that is valid in both.

Expected behavior

The binary deployment path used for SFTP operations should be resolved from within the SFTP session itself (e.g. via realpath ./pwd on the SFTP channel after connecting, or by using a path relative to the SFTP session's own starting directory) rather than reusing a path obtained from a separate shell exec probe. The two channels can have different visible filesystem roots, and only the SFTP-visible one is valid for the SFTP upload.

Workaround attempted (does not work)

Changing the DSM user's home directory in /etc/passwd to the SFTP-visible path (e.g. /homes/<user>) was considered, but is not viable: that path does not exist in the real filesystem at all (only inside internal-sftp's synthesized view), so it would break normal shell logins and any tooling relying on $HOME, without actually fixing the mismatch (internal-sftp's virtual mapping isn't derived from /etc/passwd in the first place).

Current workaround

Skip the Desktop SSH remote environment feature; install the Claude Code CLI natively on the NAS and drive it over a plain SSH/tmux session instead.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗