Introduction

Git fetch unable to access repository errors occur when Git cannot establish a connection to the remote repository, preventing synchronization of commits and branches. This manifests as fatal: unable to access repository, fatal: repository not found, fatal: authentication failed, or fatal: could not read from remote repository. Common causes include SSH key not configured or expired, HTTPS credentials missing or incorrect, TLS/SSL certificate verification failures, proxy or firewall blocking Git traffic, remote URL misconfigured, repository moved or deleted, access permissions revoked, Git LFS authentication issues, and CI/CD pipeline missing credentials. The fix requires understanding Git's authentication mechanisms (SSH vs HTTPS), configuring proper credentials, handling TLS certificates, and setting up network access. This guide provides production-proven troubleshooting for Git fetch failures across local development, corporate networks, and CI/CD pipelines.

Symptoms

  • fatal: unable to access 'https://github.com/org/repo.git/': Could not resolve host
  • fatal: repository 'https://github.com/org/repo.git/' not found
  • fatal: Authentication failed for 'https://github.com/org/repo.git/'
  • fatal: Could not read from remote repository. Please make sure you have the correct access permissions
  • ssh: connect to host github.com port 22: Connection timed out
  • fatal: unable to access: SSL certificate problem: unable to get local issuer certificate
  • fatal: remote error: Repository not found
  • error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL
  • Git fetch hangs indefinitely
  • fatal: The remote end hung up unexpectedly

Common Causes

  • SSH key not added to Git hosting account (GitHub, GitLab, Bitbucket)
  • SSH key permissions too open (not 600)
  • SSH agent not running or key not loaded
  • HTTPS credentials cached incorrectly
  • Personal Access Token (PAT) expired or revoked
  • TLS certificate self-signed or from untrusted CA
  • Corporate proxy blocking Git traffic
  • Firewall rules blocking SSH (port 22) or HTTPS (port 443)
  • Remote URL using wrong protocol (SSH vs HTTPS)
  • Repository transferred to different organization
  • Repository made private without updating access
  • CI/CD missing secrets or tokens
  • Git LFS requiring separate authentication
  • Rate limiting from anonymous requests

Step-by-Step Fix

### 1. Diagnose connection failure

Identify the specific error:

```bash # Verbose output shows where connection fails GIT_CURL_VERBOSE=1 GIT_TRACE=1 git fetch origin 2>&1

# Test SSH connection ssh -T git@github.com # Expected: Hi <username>! You've successfully authenticated

# Test HTTPS access curl -I https://github.com/org/repo.git

# Check current remote URL git remote -v

# Verify remote URL format git config --get remote.origin.url

# Check if repository exists (public repos) curl -s https://api.github.com/repos/org/repo | jq '.name'

# Test Git protocol access git ls-remote --heads origin ```

Verify network connectivity:

```bash # Test SSH port (port 22 for GitHub) nc -zv ssh.github.com 22

# If port 22 blocked, try port 443 (GitHub supports SSH over 443) nc -zv ssh.github.com 443

# Test HTTPS connectivity curl -v https://github.com

# Check DNS resolution nslookup github.com dig github.com

# Corporate network - check proxy echo $HTTP_PROXY echo $HTTPS_PROXY echo $NO_PROXY ```

### 2. Fix SSH authentication

Generate and configure SSH key:

```bash # Check existing SSH keys ls -la ~/.ssh/id_*

# Generate new Ed25519 key (recommended) ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/id_ed25519

# Or RSA 4096-bit for older systems ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f ~/.ssh/id_rsa

# Fix permissions (critical - SSH refuses keys with wrong permissions) chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub

# Copy public key to clipboard cat ~/.ssh/id_ed25519.pub | clip # Windows cat ~/.ssh/id_ed25519.pub | pbcopy # macOS cat ~/.ssh/id_ed25519.pub | xclip -selection clipboard # Linux

# Add public key to GitHub/GitLab/Bitbucket settings # GitHub: Settings > SSH and GPG keys > New SSH key # GitLab: Settings > SSH Keys # Bitbucket: Personal settings > SSH keys

# Test connection ssh -T git@github.com # Expected: Hi <username>! You've successfully authenticated

# For GitLab ssh -T git@gitlab.com # Expected: Welcome to GitLab, @username! ```

Configure SSH agent:

```bash # Start SSH agent eval "$(ssh-agent -s)"

# Add key to agent ssh-add ~/.ssh/id_ed25519

# Verify key loaded ssh-add -l

# For Windows Git Bash, ensure ssh-agent service running # Services > OpenSSH Authentication Agent > Running

# Auto-load key on shell startup (~/.bashrc or ~/.zshrc) cat >> ~/.bashrc << 'EOF' eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519 2>/dev/null EOF ```

SSH configuration for port 443 (if port 22 blocked):

```bash # GitHub supports SSH over port 443 cat >> ~/.ssh/config << 'EOF' Host github.com HostName ssh.github.com Port 443 User git IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes EOF

# Reload SSH agent ssh-add -D ssh-add ~/.ssh/id_ed25519

# Test ssh -T git@github.com ```

### 3. Fix HTTPS authentication

Personal Access Token (GitHub):

```bash # Generate PAT: GitHub > Settings > Developer settings > Personal access tokens # Select scopes: repo (full control of private repositories)

# Use PAT as password in HTTPS URL git clone https://<username>:<token>@github.com/org/repo.git

# Or configure credential helper to cache token git config --global credential.helper store # Permanent storage git config --global credential.helper 'cache --timeout=31536000' # Cache 1 year

# Clear cached credentials if needed git credential reject # Enter: protocol=https\nhost=github.com\n\n

# Re-authenticate on next fetch git fetch origin # Enter username and paste token as password ```

Git credential manager (Windows/macOS):

```bash # Windows: Git Credential Manager stores in Windows Credential Manager git config --global credential.helper manager

# macOS: Keychain integration git config --global credential.helper osxkeychain

# List stored credentials # Windows: Control Panel > Credential Manager > Windows Credentials # macOS: Keychain Access > search for "github"

# Clear and re-add git credential reject echo -e "protocol=https\nhost=github.com" | git credential reject ```

OAuth token for GitLab:

```bash # GitLab: Settings > Access Tokens # Select scopes: api, read_user, read_api

# Use token git clone https://oauth2:<token>@gitlab.com/org/repo.git

# Or configure remote git remote set-url origin https://oauth2:<token>@gitlab.com/org/repo.git ```

### 4. Fix TLS certificate errors

Self-signed certificates (corporate Git servers):

```bash # Option 1: Add certificate to trusted store (recommended) # Download certificate openssl s_client -showcerts -connect git.company.com:443 </dev/null 2>/dev/null \ | openssl x509 -outform PEM > company-cert.pem

# Add to system trust store # macOS: sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain company-cert.pem # Linux: sudo cp company-cert.pem /usr/local/share/ca-certificates/ && sudo update-ca-certificates # Windows: Import to Trusted Root Certification Authorities

# Option 2: Configure Git to trust specific CA git config --global http.sslCAInfo /path/to/company-cert.pem

# Option 3: Disable SSL verification (NOT recommended for production) git config --global http.sslVerify false ```

Corporate proxy with SSL inspection:

```bash # Get proxy's CA certificate # Usually provided by IT department

# Configure Git to use corporate CA git config --global http.sslCAInfo /path/to/corporate-ca.pem

# If using credential helper with proxy git config --global http.proxy http://user:pass@proxy.company.com:8080 git config --global https.proxy https://user:pass@proxy.company.com:8080 ```

Verify certificate chain:

```bash # Check certificate chain openssl s_client -showcerts -connect github.com:443

# Verify certificate openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt server.crt

# For Git LFS with custom certificates git config --global lfs.https://github.com.sslVerify true git config --global lfs.https://github.com.sslCAInfo /path/to/ca.pem ```

### 5. Fix proxy and firewall issues

Configure Git for proxy:

```bash # Set HTTP proxy git config --global http.proxy http://proxy.company.com:8080

# Set HTTPS proxy git config --global https.proxy https://proxy.company.com:8080

# Proxy with authentication git config --global http.proxy http://username:password@proxy.company.com:8080

# Exclude internal repos from proxy git config --global http.noProxy host1.internal.com,host2.internal.com

# Remove proxy if no longer needed git config --global --unset http.proxy git config --global --unset https.proxy ```

Corporate firewall rules:

```bash # Required ports for Git hosting: # GitHub: SSH port 22 (or 443), HTTPS port 443 # GitLab: SSH port 22, HTTPS port 443 # Bitbucket: SSH port 22, HTTPS port 443 # Azure DevOps: HTTPS port 443

# Test port connectivity telnet github.com 443 nc -zv github.com 443

# If blocked, request IT to whitelist: # - github.com, *.github.com # - gitlab.com, *.gitlab.com # - bitbucket.org, *.bitbucket.org # - api.github.com (for API calls) # - objects.githubusercontent.com (for GitHub assets)

# Alternative: Use SSH over port 443 (GitHub) git remote set-url origin git@github.com:org/repo.git # With SSH config for port 443 (see step 2) ```

### 6. Fix CI/CD authentication

GitHub Actions:

```yaml # .github/workflows/ci.yml jobs: build: steps: # Default: GITHUB_TOKEN automatically provided - uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }}

# For private submodules, use PAT - uses: actions/checkout@v4 with: submodules: recursive token: ${{ secrets.GIT_PAT }}

# SSH for private repositories - name: Setup SSH run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan github.com >> ~/.ssh/known_hosts git config --global url."git@github.com:".insteadOf "https://github.com/"

  • name: Checkout
  • run: git clone git@github.com:org/repo.git
  • `

GitLab CI:

```yaml # .gitlab-ci.yml variables: GIT_STRATEGY: clone GIT_DEPTH: 0 # Full history

stages: - build

build: stage: build script: - git fetch origin - ./build.sh

# For private submodules before_script: - apt-get update && apt-get install -y openssh-client - mkdir -p ~/.ssh - echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan github.com gitlab.com >> ~/.ssh/known_hosts - chmod 644 ~/.ssh/known_hosts - git config --global url."git@github.com:".insteadOf "https://github.com/" ```

Jenkins:

```groovy // Jenkinsfile pipeline { agent any

environment { GIT_SSH_KEY = credentials('github-ssh-key') GIT_PAT = credentials('github-pat') }

stages { stage('Checkout') { steps { // SSH method sshagent(['github-ssh-key']) { sh 'git clone git@github.com:org/repo.git' }

// HTTPS method // sh 'git clone https://${GIT_PAT}@github.com/org/repo.git' } } } } ```

### 7. Fix repository access issues

Repository moved or renamed:

```bash # Check if repository moved curl -s https://api.github.com/repos/old-org/old-name | jq '.message, .moved_to'

# Update remote URL git remote set-url origin https://github.com/new-org/new-name.git

# Verify git remote -v git fetch origin ```

Repository made private:

```bash # If you had access before, ensure credentials still valid # GitHub: Check if you're still a collaborator # GitLab: Check project members # Bitbucket: Check repository access

# Re-authenticate git credential reject git fetch origin # Will prompt for credentials

# If using SSH, verify key still authorized ssh -T git@github.com ```

Transfer between organizations:

```bash # When repository transferred, update all remotes git remote -v # Check current URL

# Update origin git remote set-url origin https://github.com/new-org/repo.git

# Update all tracked branches git fetch --all --prune

# Update upstream tracking git branch -u origin/main main ```

### 8. Advanced debugging

Enable detailed Git tracing:

```bash # Maximum verbosity export GIT_TRACE=1 export GIT_TRACE_PACKET=1 export GIT_TRACE_PERFORMANCE=1 export GIT_CURL_VERBOSE=1 export LIBCURL_TRACE=1

# Run fetch git fetch origin 2>&1 | tee git-debug.log

# Analyze log for: # - Connection establishment # - Authentication method used # - Certificate verification # - HTTP response codes ```

Network packet capture:

```bash # Capture Git traffic (requires admin/root) # Linux tcpdump -i any -s 0 -w git-traffic.pcap port 22 or port 443

# Windows (Wireshark) # Filter: tcp.port == 22 or tcp.port == 443

# macOS sudo tcpdump -i en0 -s 0 -w git-traffic.pcap port 22 or port 443

# Analyze in Wireshark for connection issues ```

Git LFS authentication:

```bash # LFS requires separate authentication sometimes git lfs install

# Configure LFS authentication git config --global lfs.https://github.com.username your-username

# Or use credential helper git config --global credential.helper store

# Test LFS fetch git lfs fetch --all

# If LFS objects missing git lfs pull ```

Prevention

  • Use SSH keys with ssh-agent for automatic authentication
  • Store credentials in system keychain (Git Credential Manager, Keychain)
  • Rotate Personal Access Tokens before expiration (set calendar reminder)
  • Use OAuth apps or GitHub Apps for automated access
  • Configure SSH config file for consistent connection settings
  • Add corporate CA certificates to trusted store
  • Document proxy requirements for new team members
  • Use deploy keys for CI/CD instead of personal tokens
  • Monitor repository access in Git hosting settings
  • Set up SSH key expiration notifications
  • **Git fatal shallow unable to resolve**: Shallow clone history insufficient
  • **Git push rejected non-fast-forward**: Force push required or fetch first
  • **Git fatal invalid refspec**: Malformed refspec syntax
  • **Git submodule not updating**: Submodule uses separate authentication
  • **403 Forbidden**: Access denied, check permissions