Bug
SSHConnect() in internal/hetzner/client.go (line 282) hardcodes the SSH private key lookup to ~/.ssh/id_ed25519 and ~/.ssh/id_rsa. If the user's SSH key has a different filename (e.g. ~/.ssh/my_project_key), Specter cannot connect even though the correct public key is uploaded to Hetzner and configured via ssh_key_name.
Steps to Reproduce
- Generate an SSH key with a custom name:
ssh-keygen -t ed25519 -f ~/.ssh/my_project_key
- Upload it to Hetzner:
hcloud ssh-key create --name my-key --public-key-from-file ~/.ssh/my_project_key.pub
- Run
specter init — picks up my-key correctly
- Run
specter image build
- VM is created, boots, but SSH connection hangs indefinitely (retrying every 3s with the wrong key)
Expected Behavior
Specter should resolve the local private key path from the configured ssh_key_name, or allow the user to specify the private key path in the config. SSH agent forwarding (SSH_AUTH_SOCK) could also be checked as a fallback.
Actual Behavior
SSHConnect() only tries ~/.ssh/id_ed25519 then ~/.ssh/id_rsa. If neither matches the key uploaded to Hetzner, the connection fails silently in a retry loop with no error message to the user.
Relevant Code
// internal/hetzner/client.go:282-313
func SSHConnect(ip string) (*ssh.Client, error) {
home, _ := os.UserHomeDir()
keyBytes, err := os.ReadFile(filepath.Join(home, ".ssh", "id_ed25519"))
if err != nil {
keyBytes, err = os.ReadFile(filepath.Join(home, ".ssh", "id_rsa"))
// ...
}
}
Proposed Fix
I'd like to contribute a fix. The approach would be:
- Add an optional
ssh_key_path field to the config (~/.specter/config.yaml)
- If set, use that path directly
- If not set, try the SSH agent (
SSH_AUTH_SOCK) first, then fall back to the current id_ed25519 / id_rsa defaults
- Surface a clear error message if no usable key is found, instead of silently retrying
Workaround
Symlink your key to the default path:
mv ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.backup
ln -s ~/.ssh/my_project_key ~/.ssh/id_ed25519
Environment
- Specter v0.1.0
- macOS (darwin/arm64)
- SSH key type: ed25519 with custom filename
Bug
SSHConnect()ininternal/hetzner/client.go(line 282) hardcodes the SSH private key lookup to~/.ssh/id_ed25519and~/.ssh/id_rsa. If the user's SSH key has a different filename (e.g.~/.ssh/my_project_key), Specter cannot connect even though the correct public key is uploaded to Hetzner and configured viassh_key_name.Steps to Reproduce
ssh-keygen -t ed25519 -f ~/.ssh/my_project_keyhcloud ssh-key create --name my-key --public-key-from-file ~/.ssh/my_project_key.pubspecter init— picks upmy-keycorrectlyspecter image buildExpected Behavior
Specter should resolve the local private key path from the configured
ssh_key_name, or allow the user to specify the private key path in the config. SSH agent forwarding (SSH_AUTH_SOCK) could also be checked as a fallback.Actual Behavior
SSHConnect()only tries~/.ssh/id_ed25519then~/.ssh/id_rsa. If neither matches the key uploaded to Hetzner, the connection fails silently in a retry loop with no error message to the user.Relevant Code
Proposed Fix
I'd like to contribute a fix. The approach would be:
ssh_key_pathfield to the config (~/.specter/config.yaml)SSH_AUTH_SOCK) first, then fall back to the currentid_ed25519/id_rsadefaultsWorkaround
Symlink your key to the default path:
Environment