SSH ProxyJump not working on Hetzner Cloud
A failed SSH login rarely needs twenty random commands. For ssh proxyjump not working on Hetzner Cloud, the fastest path is to identify the last stage that worked and inspect only the next boundary.
TL;DR: The client cannot complete one of the distinct hops from local machine to bastion to target. On Hetzner Cloud, confirm the effective target and platform layer first. Test and name each hop independently, pin per-host users and identities, then combine them with a narrow ProxyJump entry.
Who this is for: people who can reach a terminal but do not want to gamble with production access. This guide assumes basic command-line familiarity; it explains what each result means instead of assuming every SSH user is a Linux administrator.
What the error means on Hetzner Cloud
The client cannot complete one of the distinct hops from local machine to bastion to target. In this case, the environment is a Hetzner Cloud server where cloud firewalls, rescue mode, and the initial root key affect recovery. That detail matters because a command can succeed locally while a cloud policy, service manager, agent boundary, container namespace, or second SSH hop still fails.
Think of the connection as five gates: resolve the destination, open TCP, negotiate SSH, authenticate the user, then start the requested session. Write down the last gate that definitely succeeded. That single observation eliminates most irrelevant fixes.
The first five minutes: read-only checks
Run these from the same machine and account that sees the failure. Replace example names; do not paste secrets into commands or chat transcripts.
ssh -vvv -J user@bastion.example.com user@target.internal; ssh -G target-alias | grep -iE 'hostname|user|proxyjump'; nc -vz bastion.example.com 22; ssh bastion.example.com 'nc -vz target.internal 22'
curl -sS --max-time 2 http://169.254.169.254/hetzner/v1/metadata/instance-id; ip route
These commands are intentionally narrow. Record the hostname, UTC time, command exit status, and the first decisive error line. If a utility is unavailable, note that instead of installing packages or changing the server mid-investigation.
How to read the output
- Failure before bastion authentication belongs to the first hop.
- Bastion login success followed by target timeout belongs to bastion-to-target DNS, route, or firewall.
- Each hop can require a different user and identity.
- ProxyJump forwards a byte stream; it does not copy the local agent or keys to the bastion by default.
- For Hetzner Cloud, also verify this platform fact: a Hetzner Cloud server where cloud firewalls, rescue mode, and the initial root key affect recovery.
- If two observations conflict, trust effective runtime state and the narrow timestamped log over a remembered configuration file.
The goal is not to collect a wall of output. For this case, a useful conclusion is: “The client cannot complete one of the distinct hops from local machine to bastion to target. The next safe action is to test and name each hop independently, pin per-host users and identities, then combine them with a narrow ProxyJump entry.” That sentence names both the proven boundary and a small repair surface.
A safe decision path
- Confirm the target. Expand the SSH configuration and verify the hostname, address, port, and user. A correct command aimed at the wrong machine is still dangerous.
- Locate the failure stage. Use verbose client output once. Stop at the first decisive error rather than interpreting every debug line as a problem.
- Compare with server evidence. If you have console or an existing session, read a tight log window around one reproduction attempt.
- State one hypothesis. Name the observation that would disprove it. This prevents a plausible story from becoming an untested conclusion.
- Choose the smallest reversible repair. Test and name each hop independently, pin per-host users and identities, then combine them with a narrow ProxyJump entry.
- Verify from a second session. Keep the recovery path open and repeat the original user action, not merely a local status check.
Repair without losing access
Before any change, save the current effective setting or file metadata, write down the rollback, and keep an existing SSH or provider-console session open. Validate sshd configuration with the platform-supported test command before reload. Prefer reload over restart when the service and change allow it.
The key caution for this failure is: Do not enable agent forwarding merely to compensate for an unclear two-hop identity design. On Hetzner Cloud, use its supported console, recovery, or policy interface when the network path itself is unavailable. A repair is complete only when a new connection works from the user's original network and the old access path is intentionally closed.
Do not bundle cleanup into recovery. Rotating every key, upgrading the host, rewriting the firewall, and changing DNS at once creates four new explanations. Restore the narrow capability, confirm it, then schedule hardening as a separate reviewed change.
See the investigation in Tryssh
$ ssh -vvv -J user@bastion.example.com user@target.internal Collect the first decisive SSH stage, timestamp, and exit status.
Tryssh is a native macOS SSH workspace for this evidence-first loop. Saved hosts and chats stay in local SQLite, SSH keys and passphrases stay in the macOS Keychain, and the agent uses a separate execution channel from the visible terminal. Read-only commands must pass a default-deny risk gate; state-changing commands are shown exactly and wait for approval.
That helps normal SSH users because they can ask “why did this fail?” in plain language while still seeing the actual command and evidence. It does not remove operator responsibility: verify the host, protect sensitive output, and rehearse recovery on a non-production machine.
Questions operators ask
Can Tryssh fix this automatically?
Tryssh can gather and explain safe evidence, but it should not silently change authentication, firewall, routing, or service state. It proposes consequential commands for review so the person responsible for the host keeps control of blast radius.
Should I restart SSH first?
Usually not. A restart can erase useful state or lock out the only session. Capture effective configuration, service status, and a narrow log window first. If a reload or restart becomes necessary, keep a recovery session open and validate a second login before disconnecting.
What if I do not have console access?
Stop before changing access controls. Establish the provider console, physical access, another administrator, or a tested rollback path. Without one of those, even a correct change can turn a small SSH error into a full lockout.
Limits and trade-offs
Verbose SSH output can reveal hostnames, users, paths, key fingerprints, and network topology; redact it before sharing. Some commands in this guide differ across Unix and Windows shells, and managed platforms can override files through policy. Use the Hetzner Cloud documentation for the current platform contract.
This guide diagnoses a single host path. Fleet changes need canaries, concurrency limits, stop conditions, and independent rollback. A one-host success is evidence, not permission to update every machine.
Related Tryssh guides
Continue with No matching SSH algorithm on Hetzner Cloud, SSH could not resolve hostname on Hetzner Cloud, SSH ProxyJump not working on Akamai Linode, SSH config guide, SSH hardening checklist. The links cover the adjacent failure stage, the same symptom on another platform, and durable SSH configuration and hardening.
Sources and further reading
Product defaults and cloud behavior change. Prefer current first-party documentation over copied fixes, and test every command against a safe host before using it in production.
Diagnose the real host, not a hypothetical one
Download Tryssh for macOS and run the read-only checks against a host you control. The first 200 agent turns are included to start; the normal SSH terminal remains available without using credits.