Chris Lorenzo

homelab and infrastructure notes · stayz3ro

entry-32

Permission denied, and the server was fine

A read-only audit of two Oracle Cloud VMs and a GCP VM failed to log in. Where the error was Permission denied (publickey), the keys were already authorized. Batch mode never offered them, because the private keys have passphrases.

revisions rev. 1 first set 2026-10-23 last revised 2026-10-23 2 min read

Two of my cloud VMs are on Oracle Cloud, and one is on GCP. An automated read-only audit tried to log in to all three and failed on all of them. Two returned Permission denied (publickey). The third just timed out.

I was about to open the provider consoles

My first diagnosis was wrong: I thought the servers did not accept my keys. One Oracle VM did accept its original launch key, and that seemed to confirm it. So the plan was to add keys, and I was about to open the provider consoles to do it.

The servers already had the keys

The keys were already authorized on the servers. The problem was on my side: my private key files are passphrase protected. Automated tools run SSH in batch mode, which cannot prompt for a passphrase, so the key is skipped and the server answers Permission denied (publickey). That is the same error the server reports when it rejects a key.

Two checks, both on my side

The intended public key was already present in authorized_keys. I checked the private key with this command, replacing the sample path with my key’s path. It failed because the key has a passphrase:

ssh-keygen -y -P '' -f /path/to/private-key

ssh-add -l showed the key was not loaded in the agent.

Loading the keys, then checking the timeout

I ran ssh-add on the three keys once per session and entered their passphrases. That cleared the key failures.

The third VM’s timeout had another cause: its ephemeral public IP had changed after a stop/start. Once that separate address problem was accounted for, all three VMs connected.

What I check before I blame the server

I check ssh-add -l, and whether the key has a passphrase, before I blame the server. Permission denied (publickey) only means no offered key worked. That includes keys that were never offered.

For addresses, I prefer a Tailscale name over an ephemeral public IP.

It’s the same lesson as the API key my coding agent was actually sending: compare what is actually being sent, not what you think is being sent.

Related posts: Patching four cloud servers took more than apt upgrade.