This error occurs when Git cannot locate required objects during a shallow fetch operation. It typically happens when trying to update or deepen a shallow clone that references commits outside its truncated history. The fix involves unshallowing the repository, incrementally deepening the clone, or performing a fresh full clone.
The "fatal: missing objects during shallow fetch" error indicates that Git is trying to fetch commits or objects that reference history not present in your shallow repository. When you create a shallow clone using `git clone --depth N`, Git only downloads the most recent N commits and their associated objects. The repository stores boundary information in the `.git/shallow` file, marking certain commits as "grafted roots" even though they have parents in the full remote repository. During subsequent fetch operations, if the remote has been updated in ways that reference objects beyond your shallow boundary (for example, merge commits from branches you don't have), Git cannot find these objects and fails with this error. This commonly occurs in CI/CD pipelines that use shallow clones for speed but later need to perform operations requiring more history, such as determining merge bases or fetching tags connected to older commits.
The most reliable fix is to remove the shallow restriction entirely by fetching all missing history:
git fetch --unshallowThis downloads all commits from the remote, converting your repository to a complete clone. After this operation, the .git/shallow file is removed and you have full access to the repository history.
Note: This can be slow for large repositories as it downloads the entire commit history.
If a full unshallow is too time-consuming, you can incrementally deepen the history:
# Increase depth by 100 commits
git fetch --depth=100
# Increase depth by 500 commits
git fetch --depth=500
# Continue until the error resolves, then optionally unshallow
git fetch --unshallowThis approach downloads history in manageable chunks, which can help identify how much history you actually need. Some CI systems benefit from this approach as it balances speed with functionality.
If you're fetching from another shallow repository or encountering issues with shallow boundaries, use the --update-shallow flag:
git fetch --update-shallow origin mainBy default, Git refuses refs that would require updating the .git/shallow file. The --update-shallow flag allows Git to accept such refs and update the shallow boundaries accordingly.
You can also fetch all refs with this flag:
git fetch --update-shallow --update-head-ok origin '+refs/heads/*:refs/heads/*'Shallow clones often use --single-branch by default, which limits fetching to one branch. If you need other branches, edit your fetch refspec:
# Check current fetch configuration
git config --get remote.origin.fetchIf it shows something like +refs/heads/main:refs/remotes/origin/main, change it to fetch all branches:
git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
# Now fetch with unshallow
git fetch --unshallowAlternatively, manually edit .git/config and change the [remote "origin"] section's fetch line.
If the shallow clone is severely corrupted or the above steps don't work, a fresh clone may be faster:
# Backup any local changes
git stash
git diff > ~/my-changes.patch
# Move the old repository
cd ..
mv myrepo myrepo-old
# Clone fresh (full clone)
git clone https://github.com/user/repo.git myrepo
# Or shallow clone with more depth
git clone --depth 100 https://github.com/user/repo.git myrepo
# Apply your changes back
cd myrepo
git apply ~/my-changes.patchFor CI/CD pipelines, configure the clone depth appropriately based on your needs:
GitHub Actions:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full clone (recommended for version detection)
# Or use a specific depth:
# fetch-depth: 100GitLab CI:
variables:
GIT_DEPTH: 0 # Full clone
# Or:
# GIT_DEPTH: 100 # Last 100 commitsAzure DevOps:
steps:
- checkout: self
fetchDepth: 0 # Full cloneUsing fetch-depth: 0 prevents most shallow-related issues at the cost of longer clone times.
### Understanding Shallow Clone Limitations
Shallow clones are designed for specific use cases where you only need recent history. They become problematic when:
- Merge operations need to find common ancestors that are beyond the shallow boundary
- Git describe tries to find the nearest tag, which may be outside the shallow history
- Submodules reference commits not in the shallow clone
- Cherry-picking commits from branches with divergent history
### The Shallow File Mechanism
Git stores shallow boundary information in .git/shallow. Each line contains a commit SHA that Git treats as a root commit (no parents). When fetching, if a new commit's ancestry chain leads to a commit not in your repository and not listed in shallow, Git fails with the missing objects error.
### Partial Clone vs Shallow Clone
Git 2.22+ introduced partial clones (--filter=blob:none) which are different from shallow clones:
# Partial clone - omits blobs, but keeps full commit history
git clone --filter=blob:none https://github.com/user/repo.git
# Shallow clone - truncates commit history
git clone --depth 1 https://github.com/user/repo.gitPartial clones are often better for CI/CD as they maintain full commit graph but defer blob downloads, avoiding many shallow-related issues.
### Diagnosing Missing Objects
To identify which objects are missing:
# Check repository integrity
git fsck --full
# Verify connectivity
git rev-list --objects --all | git cat-file --batch-check
# See what's in the shallow file
cat .git/shallow### Network and Server Considerations
Some Git servers may have limitations on serving certain objects to shallow clones, especially:
- Self-hosted GitLab with aggressive garbage collection
- Mirrors that don't maintain full object stores
- Repositories with rewritten history (force-pushed)
If problems persist, check with your Git server administrator about object availability.
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git