infiniflow/ragflow · critical · SandboxProviderConfigError
Failed to connect to SSH host {self.username}@{self.host}:{s
Error message
Failed to connect to SSH host {self.username}@{self.host}:{self.port}: {exc} What it means
Raised as SandboxProviderConfigError by _assert_connectivity when creating the SSH client or running the probe command throws any non-config exception (the original is chained via 'from exc'). It wraps paramiko/OS-level failures — authentication errors, DNS resolution, refused connections, socket timeouts — into a config error with user@host:port context. The blanket except is deliberate: any transport failure must abort initialization.
Source
Thrown at agent/sandbox/providers/ssh.py:274
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",
"description": "Remote host that will execute generated code.",
},
"port": {
"type": "integer",
"required": True,
"label": "SSH Port",View on GitHub (pinned to 554fb1133a)
Solutions
- Read the chained original exception ('from exc') — it names the real cause (auth, DNS, timeout, host key)
- Verify reachability: ssh -p <port> user@host from the same machine
- Fix credentials: correct password, or a valid private key/passphrase pair
- For unknown-host rejections, ship a known_hosts file and set the known_hosts config option
Example fix
# before
provider.initialize({"host": "10.0.0.5", "port": 22, "username": "u", "password": "wrong"})
# -> SandboxProviderConfigError: Failed to connect ... Authentication failed.
# after
provider.initialize({"host": "10.0.0.5", "port": 22, "username": "u", "private_key": key_path, "known_hosts": "/etc/ragflow/known_hosts"}) Defensive patterns
Strategy: retry
Validate before calling
import socket
try:
socket.create_connection((host, port), timeout=5).close()
except OSError:
raise RuntimeError(f"SSH host {host}:{port} unreachable; check network/firewall") Try / catch
from agent.sandbox.providers.base import SandboxProviderConfigError
try:
provider.initialize(config)
except SandboxProviderConfigError as e:
cause = e.__cause__ # real paramiko/OS error
if isinstance(cause, (socket.timeout, ConnectionError)):
retry_with_backoff(provider.initialize, config, attempts=3)
else:
raise Prevention
- Read e.__cause__ to separate auth vs network vs host-key failures before retrying
- Only retry transient classes (timeouts, resets); never retry authentication failures
- Pre-seed known_hosts via ssh-keyscan so RejectPolicy cannot surprise you on first connect
When it happens
Trigger: initialize()/create_instance() with wrong password or bad private key (paramiko.AuthenticationException); unreachable host (DNS failure, firewall drop -> socket timeout on self.timeout); sshd not listening on the port; host key rejected by RejectPolicy because the host is unknown in known_hosts.
Common situations: Typo'd host/port/username in the sandbox config; rotated credentials or expired keys; security group / firewall blocking port 22 (or custom port); first connection to a host with no known_hosts entry while the provider is fail-closed on unknown hosts.
Related errors
- SSH connectivity check failed on {self.username}@{self.host}
- Failed to load SSH private key. {errors}
- WhatsApp session is not running.
- Failed to update memory
- Invalid SSH provider configuration.
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/2c7eb70d40facb07.
Report an issue: GitHub.