Lesstep
Bitbucket Cloud · Git over SSH · Checked October 30, 2026

Bitbucket: "git@bitbucket.org: Permission denied (publickey)."

Bitbucket Cloud answers this when none of the keys your ssh offered is on a Bitbucket account, or on the repository as an access key. It answers the same when ssh offered no key at all. So first find out which keys ssh offered. If it started after you moved your remotes to ssh.bitbucket.org, which Atlassian asks for by December 10, 2026, look at your ~/.ssh/config first.

The whole answer

What git printed on October 30, 2026 (Git for Windows 2.53 with its OpenSSH 10.2), for a public repository, with a test key that is on no Bitbucket account. With no key at all, the answer was the same:

git ls-remote git@ssh.bitbucket.org:<workspace>/<repo>.git
git@ssh.bitbucket.org: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Over SSH, a public repository needs a key Bitbucket knows, too. Over HTTPS, git ls-remote listed the same public repository with no credentials. With the old address, the first line starts with git@bitbucket.org: instead.

See which keys ssh offered

Run ssh with -v against the host in your remote (git remote -v shows it). Use the ssh that git uses; on Windows that is not always the one you type (below):

ssh -vT git@ssh.bitbucket.org

The lines that matter, from our test key named bitbucket_work (fingerprint shortened):

debug1: Authentications that can continue: publickey
debug1: Offering public key: bitbucket_work ED25519 SHA256:…
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
git@ssh.bitbucket.org: Permission denied (publickey).

When it works, Atlassian's setup guides show authenticated via ssh key. and You can use git to connect to Bitbucket. Shell access is disabled.

It started after the move to ssh.bitbucket.org

Atlassian's setup guides suggest a key name such as bitbucket_work, and this block in ~/.ssh/config (Set up personal SSH keys on Linux):

Host bitbucket.org
  AddKeysToAgent yes
  IdentityFile ~/.ssh/bitbucket_work

The block applies only to the host name bitbucket.org. After git remote set-url to ssh.bitbucket.org, or the insteadOf rule, ssh connects to ssh.bitbucket.org, and the key is no longer named for it. ssh -G prints what ssh would use, without connecting (OpenSSH 10.2, October 30, 2026):

ssh -G bitbucket.org \
  | grep -i identityfile
identityfile ~/.ssh/bitbucket_work

ssh -G ssh.bitbucket.org \
  | grep -i identityfile
identityfile ~/.ssh/id_rsa
identityfile ~/.ssh/id_ecdsa
identityfile ~/.ssh/id_ecdsa_sk
identityfile ~/.ssh/id_ed25519
identityfile ~/.ssh/id_ed25519_sk

It may keep working for a while. A key the ssh-agent holds is offered to every host, and AddKeysToAgent yes put it there the last time you used the old address. After a reboot, or in a terminal with no agent, the key is not offered any more, and Bitbucket answers Permission denied (publickey). Name both hosts:

Host bitbucket.org ssh.bitbucket.org
  AddKeysToAgent yes
  IdentityFile ~/.ssh/bitbucket_work

Several Bitbucket accounts on one machine. Atlassian's Managing multiple Bitbucket user SSH keys on one device uses a made-up host name for each account:

Host bitbucket.org-work
  HostName bitbucket.org
  User git
  IdentityFile ~/.ssh/bitbucket_work
  IdentitiesOnly yes

Remotes like git@bitbucket.org-work:<workspace>/<repo>.git connect to the HostName, which is still bitbucket.org, so the brownouts from November 12 hit them. The insteadOf rule does not rewrite them either: git 2.53 rewrote git@bitbucket.org:… and left git@bitbucket.org-work:… as it was. Change HostName to ssh.bitbucket.org in each block. ssh then looks up the host key under ssh.bitbucket.org, so known_hosts needs that name (the lines and the fingerprints).

On Windows: two ssh programs, two agents

With Git for Windows on Windows 11, there are two OpenSSH clients. On our machine on October 30, 2026:

Both read the same .ssh folder in your user profile, but each uses its own agent. Git's ssh finds its agent through SSH_AUTH_SOCK, which eval $(ssh-agent) in Git Bash sets for that window. Windows' ssh uses the OpenSSH Authentication Agent service. A key added with one ssh-add is not in the other agent, so ssh -T in PowerShell can succeed while git fails. With no agent running, they said:

# Git Bash
ssh-add -l
Could not open a connection to your authentication agent.

# PowerShell
ssh-add -l
Error connecting to agent: No such file or directory

Use one of them for both. Atlassian's Windows guide makes git use Windows' ssh:

git config --global core.sshCommand C:/Windows/System32/OpenSSH/ssh.exe

On our machine the service was Stopped, with the startup type Disabled, and Windows does not start a disabled service. The same guide's line for starting it automatically names sshd, the SSH server, which was not installed here (Cannot find any service with service name 'sshd'.). The agent's service is ssh-agent. The first two lines need PowerShell as administrator:

Set-Service ssh-agent `
  -StartupType Automatic
Start-Service ssh-agent
ssh-add $HOME\.ssh\bitbucket_work

Or keep git's own ssh and let ~/.ssh/config name the key for both host names, as above: an IdentityFile line works with no agent at all.

Where the key has to be

Also: on Linux and macOS, ssh ignores a private key that others can read, and Atlassian's Permission denied (publickey) article gives chmod 600. Git for Windows' ssh used our test key with mode 644 without a word. A network that blocks port 22 fails before any key is tried, with a timeout or a refused connection, not this message.

From IntelliJ IDEA

IntelliJ IDEA runs the git set in Settings › Version Control › Git › Path to Git executable, and that git runs its own ssh, so all of the above applies as in a terminal: the same ~/.ssh/config, and on Windows, Git's own ssh unless core.sshCommand says otherwise. JetBrains' page for these settings has no separate SSH option. An agent you started in one Git Bash window is known only to that window, so git started by the IDE does not see it; the IdentityFile line or Windows' agent service works for both. For projects opened from \\wsl$, the IDE uses Git from WSL, with the keys and config in WSL's own ~/.ssh.

Pull Request Inbox for Bitbucket, a plugin by Lesstep for JetBrains IDEs 2024.1 or later, reads the workspace and repository from your git remote, SSH or HTTPS, ssh.bitbucket.org included, and talks to Bitbucket's REST API with your Atlassian e-mail and an API token, not over SSH. So the review inbox, diffs and discussions keep working while git's SSH is failing, during the brownouts too. They are free; approving, commenting and merging are Pro (US$1.50 a month, with a 30-day trial).

Get it on JetBrains Marketplace

Bitbucket and Atlassian are trademarks of Atlassian; IntelliJ IDEA is a trademark of JetBrains s.r.o.; Windows is a trademark of Microsoft. This page is not affiliated with or endorsed by any of them.

More: Bitbucket Cloud SSH moves to ssh.bitbucket.org · "You may not have access to this repository" · "The requested URL returned error: 410" · Bitbucket pull request plugins for IntelliJ IDEA, compared · 日本語