jdx/mise · error · eyre::Report

remote upload to '{}' failed with {status}

Error message

remote upload to '{}' failed with {status}

What it means

Thrown by SshSession::status_with_stdin when the binary-upload pipeline ('ssh host sh -c "cat > <remote path> ..."' with the file on stdin) exits non-zero. The upload is a streamed cat over ssh, so failures come from the remote side of that pipeline: unwritable/missing target directory, full disk, quota, connection drops mid-stream, or ssh-level auth/network errors.

Source

Thrown at src/system/remote.rs:1538

        let status = Command::new(&self.ssh).args(args).status()?;
        if !status.success() {
            bail!(
                "remote command on '{}' failed with {status}",
                self.host.name
            );
        }
        Ok(())
    }

    fn status_with_stdin(&self, remote_argv: &[&str], input: File) -> Result<()> {
        let args = self.args(false, remote_argv);
        info!("$ {} {}", self.ssh.display(), shell_words::join(&args));
        let status = Command::new(&self.ssh)
            .args(args)
            .stdin(Stdio::from(input))
            .status()?;
        if !status.success() {
            bail!("remote upload to '{}' failed with {status}", self.host.name);
        }
        Ok(())
    }

    fn upload_executable(&self, local: &Path, remote: &str) -> Result<()> {
        let file = File::open(local)
            .wrap_err_with(|| format!("failed to open mise binary {}", local.display()))?;
        self.status_with_stdin(
            &[
                "sh",
                "-c",
                &format!(
                    "cat > {} && chmod 700 {}",
                    shell_quote(remote),
                    shell_quote(remote)
                ),
            ],
            file,

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Check the remote preconditions: ssh <host> 'test -w <dir> && df -h <dir>' for the target directory and free space
  2. Fix permissions/ownership of the remote target path for the configured SSH user
  3. For ssh 255, resolve auth/connectivity (identity_file, port, ConnectTimeout) before retrying the upload
  4. Retry after freeing disk space — mid-stream drops are transient on unstable links

Example fix

# before: upload target missing/unwritable
ssh deploy@web-1 'ls -ld /home/deploy/.local/share/mise'  # No such file or directory

# fix on remote
ssh deploy@web-1 'mkdir -p ~/.local/share/mise && chmod u+w ~/.local/share/mise'

# then re-run: mise bootstrap --host web-1
Defensive patterns

Strategy: retry

Validate before calling

# Pre-flight the upload destination before triggering provisioning:
ssh deploy@web-1 'DIR="$(dirname /path/to/target)"; test -d "$DIR" && test -w "$DIR" && df -h "$DIR" || echo PRECONDITION-FAILED'

Try / catch

let mut attempt = 0;
loop {
    attempt += 1;
    match session.upload_executable(&local, remote_path).await {
        Err(e) if attempt < 3 && e.to_string().contains("remote upload") => {
            tokio::time::sleep(std::time::Duration::from_secs(2u64 * attempt)).await; // transient reset: backoff and retry
        }
        other => break other?,
    }
}

Prevention

When it happens

Trigger: Remote staging directory does not exist or lacks write permission for the SSH user; remote filesystem full (exit from cat/dd); connection reset during a large binary transfer; ssh 255 because keys/BatchMode blocked auth.

Common situations: First deploy to a fresh host without the expected directory layout; small VPS disks filling up; restrictive umask/ACLs on shared hosts; flaky networks truncating long uploads.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/2a140579b02f503f. Report an issue: GitHub.