How to fix Permission denied (publickey). CircleCI checkout key may be invalid or revoked in Git

GitINTERMEDIATEMEDIUMUpdated Dec 6, 2025· 139 views

This error occurs when CircleCI cannot authenticate to your Git repository because the SSH checkout key has been deleted, revoked, or is misconfigured. The fix involves regenerating or adding a new deploy key in both CircleCI and your Git hosting provider.

Quick fix

Fixes Permission denied (publickey). CircleCI checkout key may be invalid or revoked

# Using CircleCI CLI (if installed)
circleci project settings --delete-checkout-key <fingerprint>
  1. Check the current checkout key status in CircleCI
  2. Verify the deploy key exists in your Git repository
  3. Remove the invalid SSH key from CircleCI
  4. Add a new deploy key in CircleCI
git — error
# Using CircleCI CLI (if installed)
circleci project settings --delete-checkout-key <fingerprint>
Permission denied (publickey). CircleCI checkout key may be invalid or revoked

What this error means

This error indicates that CircleCI's automated checkout step failed because the SSH key it uses to authenticate with your Git repository (GitHub, GitLab, Bitbucket) is no longer valid. CircleCI uses SSH deploy keys to clone your repository at the start of each build. When you see "Permission denied (publickey)" followed by the CircleCI-specific message about the checkout key being invalid or revoked, it means the SSH key pair has become out of sync. This typically happens when: 1. Someone deleted the deploy key from your GitHub/GitLab/Bitbucket repository settings 2. The SSH key was regenerated in CircleCI but not updated in the repository 3. The repository was transferred to a different organization or user 4. Access permissions to the repository changed The checkout step is one of the first things CircleCI does in a pipeline, so this error will cause your entire build to fail immediately before any tests or deployments can run.

Typical symptoms

  • CircleCI builds fail immediately at the 'Checkout code' step
  • Error message shows 'Permission denied (publickey)' in CircleCI logs
  • All builds in the project fail with the same SSH authentication error
  • Builds worked previously but suddenly started failing
  • Error appears after repository transfer or organization changes
  • New CircleCI project fails on first build
  • Error occurs after someone modified repository deploy keys
  • Pipeline fails with 'fatal: Could not read from remote repository'

Common causes

  1. Deploy key was deleted from the GitHub/GitLab/Bitbucket repository settings
  2. CircleCI project SSH key was regenerated but repository deploy key was not updated
  3. Repository was moved to a different organization or owner
  4. Repository visibility changed (e.g., from public to private)
  5. Organization admin removed or regenerated deploy keys
  6. CircleCI project was disconnected and reconnected without proper key setup
  7. Wrong SSH key type selected (deploy key vs user key)
  8. Repository access permissions were modified
  9. The deploy key expired (some Git providers support key expiration)
  10. SSH fingerprint mismatch due to key regeneration

How to fix "Permission denied (publickey). CircleCI checkout key may be invalid or revoked"

1Check the current checkout key status in CircleCI

First, verify what SSH keys CircleCI is currently using for your project:

1. Go to your CircleCI project dashboard
2. Click Project Settings (gear icon)
3. Navigate to SSH Keys in the left sidebar
4. Look at the Checkout SSH Keys section

You'll see one of these key types:
- Deploy Key: Repository-specific, read-only access (recommended)
- User Key: Uses your personal GitHub account permissions

Note the Fingerprint shown - you'll need this to match it with GitHub.

If no checkout key is listed, that's the problem - continue to step 3 to add one.

2Verify the deploy key exists in your Git repository

Check if the corresponding public key exists in your repository:

For GitHub:
1. Go to your repository on GitHub
2. Click Settings > Deploy keys
3. Look for a key with fingerprint matching CircleCI's key

For GitLab:
1. Go to your project on GitLab
2. Click Settings > Repository > Deploy Keys
3. Verify the CircleCI key is listed and enabled

For Bitbucket:
1. Go to your repository on Bitbucket
2. Click Repository settings > Access keys
3. Check if the CircleCI key exists

If the key is missing from your repository but exists in CircleCI, the key needs to be re-added. Continue to step 4.

3Remove the invalid SSH key from CircleCI

If CircleCI has an outdated or invalid key, remove it:

1. In CircleCI, go to Project Settings > SSH Keys
2. Under Checkout SSH Keys, find the problematic key
3. Click the X or Delete button next to the key
4. Confirm the deletion

Note: This will temporarily break builds until you add a new valid key.

Alternatively, use the CircleCI CLI or API:

bash
# Using CircleCI CLI (if installed)
circleci project settings --delete-checkout-key <fingerprint>
4Add a new deploy key in CircleCI

Generate and add a new checkout key:

Option A: Let CircleCI generate the key (Recommended)

1. In CircleCI, go to Project Settings > SSH Keys
2. Scroll to Checkout SSH Keys
3. Click Add Deploy Key (or Create and add key)
4. CircleCI will automatically:
- Generate a new SSH key pair
- Add the public key to your GitHub repository as a deploy key
- Configure the private key for use in builds

Option B: Add a User Key (for private dependencies)

If your build needs to access multiple private repositories:

1. Click Add User Key instead
2. Authorize CircleCI to access your GitHub account
3. This grants access to all repositories your account can access

Warning: User keys have broader access. Prefer deploy keys for single-repository access.

For GitLab or Bitbucket:

CircleCI may not auto-add keys for non-GitHub repos. You'll need to:
1. Generate a key pair manually
2. Add the private key to CircleCI
3. Add the public key to your GitLab/Bitbucket repository

5Manually add an SSH key for non-GitHub repositories

For GitLab, Bitbucket, or self-hosted Git:

Generate a new SSH key pair:

bash
# Generate an Ed25519 key (recommended)
ssh-keygen -t ed25519 -C "circleci-deploy@your-project" -f circleci_key -N ""

# Or generate an RSA key for older systems
ssh-keygen -t rsa -b 4096 -C "circleci-deploy@your-project" -f circleci_key -N ""

This creates two files:
- circleci_key (private key)
- circleci_key.pub (public key)

Add the private key to CircleCI:

1. Go to Project Settings > SSH Keys
2. Click Add SSH Key under "Additional SSH Keys"
3. Enter your Git hostname (e.g., gitlab.com, bitbucket.org)
4. Paste the contents of circleci_key (private key)
5. Click Add SSH Key

Add the public key to your repository:

bash
# Display the public key
cat circleci_key.pub

Copy this and add it as a deploy key in your repository settings.

Securely delete the local key files:

bash
rm circleci_key circleci_key.pub
6Verify the fix by re-running the pipeline

After adding the new key, trigger a new build:

1. Go to your CircleCI project dashboard
2. Click Rerun workflow from failed or Rerun from start
3. Watch the Checkout code step

Expected success:

bash
Checkout code
  Using SSH Config
  Cloning into '.'...
  done.

If it still fails, check:
- The key fingerprint matches between CircleCI and your repository
- The deploy key has read access to the repository
- For private repos, ensure the key is not read-only if write access is needed

Verify SSH connectivity manually:

You can also test from a CircleCI shell:

yaml
# Add this step temporarily to your config.yml
- run:
    name: Debug SSH
    command: |
      ssh -T git@github.com || true
      ssh-add -l
7Handle organization-owned repositories

For repositories in a GitHub Organization, additional steps may be required:

Enable OAuth App access:

1. Go to your GitHub Organization settings
2. Navigate to Third-party access > OAuth Apps
3. Find CircleCI and click Review
4. Ensure CircleCI has access to the repository

Request organization approval (if required):

If your organization restricts third-party access:
1. An organization admin must approve CircleCI's access
2. The admin can do this at: Organization Settings > Third-party access

Use SSH deploy keys instead of OAuth:

For stricter security requirements, use deploy keys:
1. Remove any user keys in CircleCI
2. Add a deploy key as described in step 4
3. Deploy keys are scoped to a single repository

Check organization SAML enforcement:

If your organization uses SAML SSO:
1. Ensure your SSH keys are authorized for SAML
2. Go to GitHub Settings > SSH and GPG keys
3. Click Configure SSO next to the relevant key
4. Authorize the key for your organization

8Update CircleCI config for custom SSH key

If using a custom SSH key (not the default checkout key), update your .circleci/config.yml:

Using the add_ssh_keys step:

yaml
version: 2.1

jobs:
  build:
    docker:
      - image: cimg/base:stable
    steps:
      # Add custom SSH key before checkout
      - add_ssh_keys:
          fingerprints:
            - "SO:ME:FI:NG:ER:PR:IN:T0:12:34:56:78:90:ab:cd:ef"

      # Now checkout will use the added key
      - checkout

      - run:
          name: Build
          command: echo "Building..."

For accessing private dependencies:

yaml
steps:
  - add_ssh_keys:
      fingerprints:
        - "key-fingerprint-for-private-dep-repo"

  - checkout

  - run:
      name: Clone private dependency
      command: git clone git@github.com:org/private-lib.git

Find the fingerprint:

The fingerprint is shown in CircleCI under Project Settings > SSH Keys after you add the key.

Advanced notes

### Debugging SSH Issues in CircleCI

Add debugging steps to your config to diagnose SSH problems:

yaml
- run:
    name: Debug SSH Configuration
    command: |
      echo "=== SSH Keys loaded ==="
      ssh-add -l

      echo "=== SSH Config ==="
      cat ~/.ssh/config || echo "No SSH config"

      echo "=== Testing GitHub SSH ==="
      ssh -vT git@github.com 2>&1 || true

      echo "=== Known Hosts ==="
      cat ~/.ssh/known_hosts || echo "No known hosts"

### Deploy Keys vs User Keys

| Feature | Deploy Key | User Key |
|---------|-----------|----------|
| Scope | Single repository | All repos user can access |
| Security | More restricted | Broader access |
| Setup | Per repository | Once per user |
| Use case | Single repo CI/CD | Multi-repo access |
| Revocation | Remove from repo | Remove from user account |

Best practice: Use deploy keys unless you specifically need access to multiple private repositories.

### Rotating SSH Keys

Periodically rotate your CircleCI SSH keys for security:

1. Generate a new key pair
2. Add the new key to CircleCI and your repository
3. Verify builds work with the new key
4. Remove the old key from both CircleCI and your repository

### Self-Hosted Git Servers

For self-hosted Git (GitHub Enterprise, GitLab self-managed):

yaml
# .circleci/config.yml
- add_ssh_keys:
    fingerprints:
      - "your-key-fingerprint"

- run:
    name: Add self-hosted Git to known hosts
    command: |
      mkdir -p ~/.ssh
      ssh-keyscan git.yourcompany.com >> ~/.ssh/known_hosts

### SSH Key Fingerprint Format Changes

CircleCI may show fingerprints in different formats:

- MD5: ab:cd:ef:12:34:56:78:90:ab:cd:ef:12:34:56:78:90
- SHA256: SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

To convert between formats:

bash
# Get MD5 fingerprint
ssh-keygen -l -E md5 -f your_key.pub

# Get SHA256 fingerprint
ssh-keygen -l -E sha256 -f your_key.pub

### CircleCI Contexts and SSH Keys

If using CircleCI Contexts for shared secrets:

1. You cannot store SSH keys in Contexts directly
2. SSH keys must be added at the project level
3. For multiple projects needing the same key, add it to each project

### Common Misconfigurations

Wrong hostname in SSH key:
Ensure the hostname in CircleCI matches exactly:
- github.com (not www.github.com)
- gitlab.com (not https://gitlab.com)

Read-only deploy key for push operations:
If your CI needs to push (e.g., release tags):
1. When adding the deploy key to GitHub, check Allow write access
2. Or use a user key instead

Key added to wrong repository:
For forked repositories, ensure the key is added to the correct repo (fork vs upstream).

### Monitoring Key Health

Set up alerts for SSH authentication failures:

yaml
# Notify on checkout failures
- checkout:
    post-checkout:
      - run:
          name: Verify checkout
          command: |
            if [ ! -f "package.json" ]; then
              echo "Checkout may have failed"
              exit 1
            fi

### Related CircleCI Errors

- "Host key verification failed" - Add the host to known_hosts
- "fatal: Could not read from remote repository" - SSH key issue
- "ERROR: Repository not found" - Wrong key or missing repo access

Frequently asked questions

What does "Permission denied (publickey). CircleCI checkout key may be invalid or" mean?
This error indicates that CircleCI's automated checkout step failed because the SSH key it uses to authenticate with your Git repository (GitHub, GitLab, Bitbucket) is no longer valid. CircleCI uses SSH deploy keys to clone your repository at the start of each build. When you see "Permission denied (publickey)" followed by the CircleCI-specific message about the checkout key being invalid or revoked, it means the SSH key pair has become out of sync.
How do I fix "Permission denied (publickey). CircleCI checkout key may be invalid or"?
This error occurs when CircleCI cannot authenticate to your Git repository because the SSH checkout key has been deleted, revoked, or is misconfigured. The fix involves regenerating or adding a new deploy key in both CircleCI and your Git hosting provider.
What causes "Permission denied (publickey). CircleCI checkout key may be invalid or"?
Deploy key was deleted from the GitHub/GitLab/Bitbucket repository settings CircleCI project SSH key was regenerated but repository deploy key was not updated Repository was moved to a different organization or owner
Is the "Permission denied (publickey). CircleCI checkout key may be invalid or" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading