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 hostfatal: repository 'https://github.com/org/repo.git/' not foundfatal: Authentication failed for 'https://github.com/org/repo.git/'fatal: Could not read from remote repository. Please make sure you have the correct access permissionsssh: connect to host github.com port 22: Connection timed outfatal: unable to access: SSL certificate problem: unable to get local issuer certificatefatal: remote error: Repository not founderror: 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
Related Errors
- **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