“Permission denied (publickey)” means an SSH server rejected the key-based login it received. In a Laravel Forge workflow, that message can come from two different connections: your computer connecting to the Forge server, or the Forge server connecting to GitHub, GitLab, or Bitbucket to fetch code. Those connections use different keys and are authorized in different places.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
Find the failing connection first, then inspect the exact key, host, and SSH username being used. The sequence below separates both hops and gives a repair path for normal servers and servers that Forge has marked as revoked.
As an Amazon Associate I earn from qualifying purchases.
Recommended Free Tools
What the error actually tells you
GitHub’s documentation defines the message plainly: a “Permission denied” error means that the server rejected your connection. The wording does not identify which key was rejected, which account was targeted, or even which connection in a deployment failed.
A Forge deployment normally involves at least two SSH trust relationships:
#1 Best Overall
| Connection (hop) | Who initiates it | Where authorization is stored | Typical symptom |
|---|---|---|---|
| Workstation to Forge server | Your laptop or desktop | Your public key in the Forge server account’s SSH-key authorization | You cannot open an SSH session to the server |
| Forge server to source-control provider | The server’s deployment process | The Forge server key registered with the repository provider or repository deploy keys | SSH works to the server, but a clone, pull, or deployment fails |
A key that fixes one hop does not automatically fix the other. Your personal workstation key should not be substituted for the server’s repository key, and adding a repository deploy key will not grant your laptop access to the server.
Identify the failing hop before changing keys
Test workstation-to-server access
Use the same server hostname, SSH username, and private-key selection that Forge or your team normally uses. Run a verbose connection from your workstation, replacing the placeholders with the values for your server:
ssh -v user@server
If this command fails, the problem is on the local-to-server hop. If it succeeds but Forge still cannot deploy, test the repository hop instead. Do not infer repository access from a successful shell login; they are separate authentications.
Test server-to-provider access
Connect to the Forge server, switch to the user that runs deployments, and test the provider host with the provider’s required SSH account. For GitHub, the standard diagnostic is:
ssh -vT [email protected]
For another provider, use its documented SSH hostname while retaining the provider’s expected SSH username. Repository URLs generally use the git user, not your personal web-account username. GitHub specifically documents that replacing git with a personal username causes public-key authentication to fail.
A successful provider test may print a message saying that shell access is not provided; that can still prove that the key was accepted. The important part is whether public-key authentication succeeds for the intended host and account.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Read verbose SSH output correctly
The -v output shows which identities SSH searches for and which ones it offers. In the identity-file lines, a marker indicating that a file is missing means SSH did not find that private-key file; it was not available to authenticate. Later, an Offering public key line means SSH actually presented that key to the server.
Use the output to answer four questions:
- Is SSH looking in the expected location, or only at unrelated default files?
- Does the private key file exist and can the current user read it?
- Is the intended key actually offered, rather than merely listed as a missing identity?
- Does the connection target the expected hostname and SSH username?
If no intended key is offered, fix local key selection or the SSH agent before changing authorization on a remote service. If the key is offered and rejected, verify that the matching public key is registered on the correct server or repository.
Repair the local key and SSH agent
Confirm which identities the agent has
Run this as the same operating-system user that will make the connection:
ssh-add -l -E sha256
The command lists fingerprints for keys currently loaded in the agent. An empty result means the agent has no identities available. Load the intended private key into the agent, or configure SSH to use that key directly, then repeat the verbose test. If the key is missing entirely, create a replacement according to your operating system’s SSH tooling and keep the private half on the workstation.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Rank #3
Register only the public half
When a service asks for an SSH key, provide the public half of the pair. Never paste a private key into Forge, a source-control provider, a ticket, or a shell command that could expose it. Compare fingerprints when possible so you know that the public key you registered corresponds to the private key SSH is offering.
Avoid mixing users with elevated commands
Do not run one diagnostic with sudo and another as your normal user without understanding the difference. An elevated shell can use a different home directory, SSH configuration, agent socket, and key set. GitHub warns that commands run with elevated privileges can therefore authenticate with a different identity than the one you intended. Repeat the test as the actual deployment or workstation user.
Fix workstation access to the Forge server
Laravel’s SSH guidance explains that adding your machine’s public key to the server lets the server identify connections from your computer and grant access. In Forge, this authorization is managed through the server’s SSH Keys area for the account you use to log in.
- On your workstation, identify the public key paired with the private key that appears in the successful
Offering public keyline. Check its fingerprint if more than one key exists. - In the Forge dashboard, open the affected server and review its SSH Keys list.
- Add the correct public key, or remove an obsolete duplicate only after confirming that no administrator or automation still depends on it.
- Confirm that the key is attached to the server account and login user you are actually using.
- Retry
ssh -v user@server. The verbose output should show the intended key being offered and accepted.
If the server has multiple system users, authorization is normally account-specific. A key installed for one account does not automatically permit login as another. Make the test with the exact username used by your Forge site or deployment instructions.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchFix Forge’s connection to the repository provider
When you can SSH into the server but a deployment fails while cloning or pulling code, repair the second hop. Forge’s deploy-key documentation describes a server SSH key that is added to connected GitHub, GitLab, or Bitbucket accounts and can be managed as a repository deploy key.
Rank #4
Verify the repository URL and SSH account
Inspect the repository configuration used by the deployment. The SSH form must point to the provider host expected by that provider and use its SSH account, normally git. A URL that embeds a personal username, points to the wrong provider hostname, or uses an HTTPS address when the deployment expects SSH can produce a misleading public-key error.
Confirm the key belongs to the intended repository
- In Forge, locate the server’s SSH key or deploy-key information for the affected connection.
- In the source-control provider, open the intended repository’s deploy-key or account SSH-key settings.
- Compare the displayed public-key fingerprint or full public key with the key Forge is using.
- Ensure the key is authorized for the correct repository, not a similarly named project, fork, or organization.
- Grant the minimum required permission. A deployment that only reads code needs read access; do not grant write access unless the workflow genuinely pushes changes.
- From the server, rerun the provider test as the deployment user:
ssh -vT [email protected]for GitHub, or the equivalent host for your provider.
Repository deploy keys are commonly scoped to one repository, while an account-level key may reach several repositories according to that account’s permissions. Choose the scope deliberately and document which server uses which key so a later rotation does not strand deployments.
Use the right fix for the observed symptom
| Observed result | Most likely failing hop | First place to inspect | Typical repair |
|---|---|---|---|
| Local SSH cannot reach the server | Workstation to Forge server | Local agent/file, server SSH Keys list, login username | Load or replace the workstation key and add its public half to the server account |
| Local SSH reaches the server, but deployment cannot clone | Forge server to provider | Repository URL, server deployment key, provider repository authorization | Use the provider’s host and git user; register the server key with read access |
| Verbose output shows a missing identity file | Key selection on the initiating machine | SSH configuration and private-key path | Correct the path or load the intended key into the agent |
| Verbose output shows “Offering public key” followed by rejection | Authorization at the destination | Matching public key, host, and account | Add the corresponding public key to the exact server or repository scope |
Only commands run with sudo fail |
Different user or agent environment | Root versus normal-user SSH configuration | Run the deployment with one consistent user and key environment |
| Forge reports a revoked server | Forge server registration state | Forge server status and reconnect workflow | Reconnect through the Forge API, install the returned public key, then reactivate the server |
Recover a revoked Forge server
A revoked server is an operational state, not merely a bad repository key. Forge’s API documents a reconnect call that returns a public key. That key must be installed on the server before the server is reactivated.
- Initiate the documented Forge server reconnect call for the revoked server.
- Capture the public key returned by the API response.
- Install that public key in the server’s SSH authorization for the account and location specified by Forge’s reconnect procedure.
- Verify that the server can accept the Forge connection without changing unrelated user keys.
- Reactivate the server in Forge.
- After reactivation, test both hops: your workstation-to-server login and the server-to-provider repository connection.
Do not treat reactivation as proof that repository authorization is fixed. The reconnect key restores Forge’s ability to manage the server; the repository deploy key still has to be present and authorized separately.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common traps that keep the error recurring
Adding the right key to the wrong place
A workstation public key belongs in the Forge server account’s SSH authorization. A server deployment key belongs in the source-control provider’s account or repository authorization. Swapping those destinations leaves the original failure unchanged.
Best Value
Testing from the wrong machine
Running ssh -vT on your laptop tests your laptop’s identities, not the identities available to the Forge deployment process. Run the repository test from the server and under the deployment user.
Using the wrong host or username
SSH keys are evaluated after the connection reaches a particular host and account. A valid key offered to the wrong hostname, or to a provider account name other than git, can still be rejected. Copy the host and user from the repository’s SSH URL instead of typing them from memory.
Leaving stale keys everywhere
Multiple old keys make verbose output difficult to interpret and increase the chance that a revoked or unrelated key is offered first. Remove only keys that are confirmed obsolete, then keep a short record of each active key’s owner, server, repository scope, and rotation date.
A repeatable diagnostic checklist
- Record the exact command or Forge deployment stage that fails.
- Decide whether the failure is workstation-to-server or server-to-provider.
- Run the relevant verbose SSH command from the correct machine and user.
- Check for missing identity files and confirm an
Offering public keyline appears for the intended key. - Verify the destination hostname and SSH username; use
gitfor provider repository access where required. - List the active agent identities with
ssh-add -l -E sha256. - Register the matching public key at the correct authorization scope.
- Retest the failing hop, then perform a complete Forge deployment test.
- If the server is revoked, complete reconnect, key installation, and reactivation before troubleshooting repository permissions again.
Security and maintenance practices
Use separate keys for personal workstation access and server-to-repository automation. Scope repository keys as narrowly as the deployment permits, prefer read-only access for pull-only workflows, and rotate keys when a team member, server, or repository relationship changes. Keep private keys out of source control and out of shared chat logs. During rotation, add and test the replacement key before removing the old one so a failed deployment does not become an access outage.
Finally, preserve the fingerprint and purpose of each active key in your operational notes. When the same error appears months later, that record lets you distinguish a missing local identity, a revoked server, an incorrectly formatted repository URL, and a genuinely unauthorized deploy key without guessing.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Free tools Windows power users keep installed
One-click scans. No signup required.




