infiniflow/ragflow · critical · SandboxProviderConfigError

SSH connectivity check failed on {self.username}@{self.host}

Error message

SSH connectivity check failed on {self.username}@{self.host}:{self.port}: {stderr or 'remote command returned non-zero exit status'}

What it means

Raised as SandboxProviderConfigError by SSHProvider._assert_connectivity when the SSH connection itself succeeds but running the command 'true' on the remote host returns a non-zero exit status. It means the transport works but the remote shell environment is broken, so the provider refuses to start. The message embeds user@host:port and the captured stderr (or a generic fallback).

Source

Thrown at agent/sandbox/providers/ssh.py:268

    def health_check(self) -> bool:
        try:
            self._assert_connectivity()
            return True
        except Exception:
            return False

    def _assert_connectivity(self) -> None:
        try:
            client = self._create_ssh_client()
            try:
                _, stderr, exit_code = self._run_remote_command(
                    client,
                    "true",
                    timeout=min(self.timeout, 10),
                )
                if exit_code != 0:
                    raise SandboxProviderConfigError(f"SSH connectivity check failed on {self.username}@{self.host}:{self.port}: {stderr or 'remote command returned non-zero exit status'}")
            finally:
                client.close()
        except SandboxProviderConfigError:
            raise
        except Exception as exc:
            raise SandboxProviderConfigError(f"Failed to connect to SSH host {self.username}@{self.host}:{self.port}: {exc}") from exc

    def get_supported_languages(self) -> List[str]:
        return ["python", "javascript", "nodejs"]

    @staticmethod
    def get_config_schema() -> Dict[str, Dict]:
        return {
            "host": {
                "type": "string",
                "required": True,
                "label": "SSH Host",
                "placeholder": "192.168.1.10",

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Test manually: ssh user@host true; echo $? — if it is non-zero, fix the remote shell environment
  2. Remove exit-non-zero statements from the account's .bashrc/.profile/.bash_profile
  3. If the account is sftp-only or forced-command, use a full shell account for this provider
  4. Correct the shell field in /etc/passwd (e.g. usermod -s /bin/bash user)

Example fix

// before: account shell exits 1 on login
$ ssh deploy@10.0.0.5 true; echo $?
1

// after: fix shell startup files / shell field
$ ssh deploy@10.0.0.5 true; echo $?
0
Defensive patterns

Strategy: try-catch

Validate before calling

import subprocess
rc = subprocess.run(["ssh", f"{user}@{host}", "-p", str(port), "true"]).returncode
if rc != 0:
    raise RuntimeError(f"remote shell broken on {host} (exit {rc}); fix shell init files")

Try / catch

from agent.sandbox.providers.base import SandboxProviderConfigError
try:
    provider.initialize(config)
except SandboxProviderConfigError as e:
    if "connectivity check failed" in str(e):
        log.error("remote shell exits non-zero on login; fix .bashrc/.profile or shell for the account")
        raise

Prevention

When it happens

Trigger: initialize() or create_instance() against a host whose default shell fails immediately (broken .bashrc/.profile exiting non-zero, no valid shell in /etc/passwd, restricted/forced command in authorized_keys that ignores 'true'); a login shell printout polluting stderr with a failing last command; sftp-only accounts.

Common situations: Hardened or chrooted SSH accounts whose forced command returns non-zero; user dotfiles that exit with an error status; managed bastion images where the shell is replaced by a wrapper; accounts restricted by rssh/sftp-only shells.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/86750a696b900062. Report an issue: GitHub.