zed-industries/zed · error
failed to upload directory via SFTP/SCP {} -> {}: {}
Error message
failed to upload directory via SFTP/SCP {} -> {}: {} What it means
When uploading a directory (the extracted remote server) over SSH, Zed tries SFTP and falls back to scp -r; this error is the final failure of the scp fallback, embedding the CLI's stderr. Neither SFTP nor SCP managed to copy the directory to the remote host.
Source
Thrown at crates/remote/src/transport/ssh.rs:454
if output.status.success() {
return Ok(());
}
let stderr = String::from_utf8_lossy(&output.stderr);
log::debug!("failed to upload directory via SFTP {src_path_display} -> {dest_path_str}: {stderr}");
}
log::debug!("using SCP for directory upload");
let output = scp_command.output().await?;
if output.status.success() {
return Ok(());
}
let stderr = String::from_utf8_lossy(&output.stderr);
log::debug!("failed to upload directory via SCP {src_path_display} -> {dest_path_str}: {stderr}");
anyhow::bail!(
"failed to upload directory via SFTP/SCP {} -> {}: {}",
src_path_display,
dest_path_str,
stderr,
);
})
}
fn start_proxy(
&self,
unique_identifier: String,
reconnect: bool,
incoming_tx: UnboundedSender<Envelope>,
outgoing_rx: UnboundedReceiver<Envelope>,
connection_activity_tx: Sender<()>,
delegate: Arc<dyn RemoteClientDelegate>,
cx: &mut AsyncApp,
) -> Task<Result<i32>> {View on GitHub (pinned to f4178619ac)
Solutions
- Reproduce manually with the paths from the message: `scp -r <src_dir> <user>@<host>:<dest>` and read the stderr Zed embedded
- Install the SSH client tools on the remote (apt-get install openssh-client / apk add openssh) so scp and sftp exist
- Verify destination writability and free space on the remote: `df -h`, `touch <dest_dir>/probe`
- Silence non-interactive shell output (.bashrc guards), since shell chatter breaks SFTP/SCP sessions
Example fix
# before: remote container without openssh-clients apk add --no-cache openssh # run on the remote # then retry the Zed remote connection; scp fallback now succeeds
Defensive patterns
Strategy: retry
Validate before calling
async fn remote_supports_scp(socket: &SshSocket, shell: ShellKind) -> bool {
socket.run_command(shell, "which", &["scp"], true).await.is_ok()
&& socket.run_command(shell, "which", &["sftp"], true).await.is_ok()
} Try / catch
match upload_dir(src, dest).await {
Err(e) if e.to_string().contains("SFTP/SCP") && attempts_left() => {
// verify remote writability and free space, then retry once
retry_after_repair().await
}
other => other,
} Prevention
- Install openssh-client on remotes used for development
- Guard remote rc files against printing during non-interactive sessions
- Keep free space monitored on frequently-used dev hosts
When it happens
Trigger: The scp -r command built for the directory upload exits non-zero: the remote lacks scp/sftp binaries, the target directory is not writable, the disk is full, or the destination path/arguments trip quoting problems.
Common situations: Minimal remotes (containers, embedded boards) without openssh-clients; connecting as a user whose home or .local/share is read-only; full server filesystems; remote shell startup files printing text that corrupts the SFTP protocol channel.
Related errors
- failed to upload file via STFP/SCP {} -> {}: {}
- build ids may only contain lowercase letters, numbers, '.',
- registry dataset requires a name
- cannot open repository on disconnected remote machine
- unknown uname: {uname:?}
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/fce30fb1fa169588.
Report an issue: GitHub.