The 'missing blob object in blobless clone' error occurs when Git cannot locate a required blob that was intentionally excluded during a partial clone. This happens when the promisor remote is unavailable or when operating offline with a blobless repository.
This error indicates that Git needs a blob (file content) that was deliberately not downloaded during a blobless partial clone, and it cannot fetch the blob on-demand from the promisor remote. A blobless clone is created using `git clone --filter=blob:none`, which downloads all commits and trees but defers blob (file content) downloads until they are actually needed. This dramatically reduces initial clone time and disk usage for large repositories. The key concept is the "promisor remote" - the remote server that "promises" to provide missing objects when requested. When you perform operations that require file contents (like `git checkout`, `git diff`, or `git blame`), Git automatically fetches the required blobs from this promisor remote. This error occurs when: 1. **The promisor remote is unreachable** - You're offline or the remote server is down 2. **The remote was removed** - The repository configuration was modified to remove the promisor remote 3. **Using --reference with blobless clones** - Reference repositories cannot provide missing blobs 4. **The blob was deleted from the remote** - Rare, but possible with force-pushes or repository cleanup
First, check if you can reach the remote repository that should provide the missing blobs:
# Check configured remotes
git remote -v
# Test connectivity to origin
git ls-remote origin
# Check if the remote is configured as a promisor
git config --get remote.origin.promisor
# Should output: trueIf you get a network error, resolve your network connectivity before continuing. The promisor remote must be accessible for Git to fetch missing blobs.
If the remote URL is wrong:
# Update the remote URL
git remote set-url origin https://github.com/username/repo.gitIf the origin remote was removed or the promisor configuration is missing, restore it:
# Check current promisor configuration
git config --list | grep promisor
# If missing, configure origin as a promisor remote
git config remote.origin.promisor true
git config remote.origin.partialclonefilter blob:noneIf origin was completely removed:
# Re-add the origin remote
git remote add origin https://github.com/username/repo.git
# Configure it as a promisor
git config remote.origin.promisor true
git config remote.origin.partialclonefilter blob:none
# Test fetching
git fetch originAfter restoring the configuration, retry your operation - Git should now be able to fetch missing blobs.
Manually fetch the specific missing blobs or trigger a bulk fetch:
# Fetch a specific missing blob (replace with actual hash)
git fetch origin abc1234
# Fetch all blobs for the current HEAD
git fetch --all
# Fetch blobs needed for checkout
git checkout HEAD -- .For a specific file or path:
# Fetch blobs for a specific directory
git fetch origin --filter=blob:none -- path/to/directory
# Force checkout which triggers blob fetch
git checkout --force HEAD -- path/to/file.txtIf individual blob fetching fails, the remote may have been cleaned up or force-pushed.
The git backfill command (Git 2.43+) efficiently downloads all missing blobs in batches:
# Check Git version
git --version
# Requires Git 2.43 or later
# Download all missing blobs
git backfill
# Backfill only recent commits
git backfill --since="2024-01-01"
# Backfill specific paths
git backfill -- src/ docs/Note: This command is experimental and behavior may change in future Git versions. It downloads blobs in batches, which is more efficient than individual on-demand fetching.
For older Git versions, fetch everything:
# Full fetch that includes all objects
git fetch --unshallow origin
# Or re-clone without filters
git clone https://github.com/username/repo.git repo-fullIf you need all blobs locally (for offline work or pushing to a new remote), convert to a full clone:
Method 1: Fetch all objects
# Remove the partial clone filter
git config --unset remote.origin.partialclonefilter
# Fetch all missing objects
git fetch origin --unshallow
# Verify no missing objects
git fsck --fullMethod 2: Re-clone locally
# Clone your blobless repo into a full clone
cd ..
git clone --no-local ./blobless-repo ./full-repo
# This forces Git to fetch all objects from the promisor remoteMethod 3: Use git repack
# Repack and include promisor objects
git repack -a -d --write-midxAfter conversion, you can push to any remote without missing blob errors.
If you're seeing this error when using git clone --reference, that's because blobless repositories cannot serve as reference repositories:
The problem:
# This will fail
git clone --reference /path/to/blobless-repo https://github.com/user/repo.git
# fatal: missing blob object...The solution - use a full clone as reference:
# First, create a full clone for reference
git clone https://github.com/user/repo.git /path/to/full-reference-repo
# Then use it as reference
git clone --reference /path/to/full-reference-repo https://github.com/user/repo.git
# Or clone without reference
git clone https://github.com/user/repo.gitFor CI/CD caching, consider alternatives:
# Use shallow clone instead of blobless for CI
git clone --depth 1 https://github.com/user/repo.git
# Or accept the full clone time for reference repositoriesIf the repository is corrupted or the promisor remote configuration cannot be restored, re-clone:
# Save any local changes first
git stash push -m "backup before re-clone"
git format-patch origin/main --stdout > my-patches.patch
# Move the broken repo aside
cd ..
mv broken-repo broken-repo-backup
# Clone fresh (blobless or full)
# For blobless (faster initial clone):
git clone --filter=blob:none https://github.com/user/repo.git
# For full (no on-demand fetching needed):
git clone https://github.com/user/repo.git
# Restore your work
cd repo
git apply ../broken-repo-backup/my-patches.patchCopy .git folder approach:
# Clone to temporary location
git clone https://github.com/user/repo.git /tmp/fresh-repo
# Copy fresh .git to broken repo
rm -rf /path/to/broken/.git
cp -r /tmp/fresh-repo/.git /path/to/broken/
# Reset to restore working directory
cd /path/to/broken
git reset --hard HEAD### Understanding Partial Clone Architecture
Partial clones use a "promisor remote" mechanism:
# Check promisor configuration
git config --get-regexp 'remote\..*\.promisor'
git config --get-regexp 'remote\..*\.partialclonefilter'
# The promisor packfiles are marked specially
ls .git/objects/pack/*.promisorThe promisor remote "promises" to provide any missing objects on demand. This contract is broken when:
- The remote is removed or renamed
- Network is unavailable
- The remote repository is deleted or made inaccessible
### Debugging Missing Objects
# Check for missing objects
git fsck --full --unreachable
# List promisor pack files
ls -la .git/objects/pack/*.promisor
# Check which objects are missing
GIT_TRACE=1 git checkout HEAD -- path/to/file 2>&1 | grep "missing"### Partial Clone Filter Types
Different filters affect what objects are initially downloaded:
# Blobless - no blobs, all trees and commits
git clone --filter=blob:none <url>
# Treeless - no blobs or trees (most aggressive)
git clone --filter=tree:0 <url>
# Size-limited - exclude large blobs
git clone --filter=blob:limit=1m <url>
# Combine filters
git clone --filter=combine:blob:none+tree:0 <url>### Working Offline with Blobless Clones
If you need to work offline with a blobless clone, pre-fetch the blobs you'll need:
# Fetch blobs for current branch
git fetch origin $(git rev-parse HEAD)
# Fetch blobs for specific paths you'll work on
git fetch origin -- src/ lib/ tests/
# Or use git backfill for recent history
git backfill --since="1 week ago"### CI/CD Considerations
For CI/CD pipelines using partial clones:
# GitHub Actions example - ensure fetch depth
- uses: actions/checkout@v4
with:
filter: blob:none # Creates blobless clone
fetch-depth: 0 # Full history
# If build needs all files, add:
- run: git fetch --all# GitLab CI example
variables:
GIT_STRATEGY: clone
GIT_DEPTH: 0 # Full history
before_script:
- git config remote.origin.promisor true
- git config remote.origin.partialclonefilter blob:none### Recovering from Corrupted Promisor State
If the .git directory is corrupted:
# Try to repair
git fsck --full
# If objects are referenced but missing, remove the references
git reflog expire --expire=now --all
git gc --prune=now
# Check packfile integrity
git verify-pack -v .git/objects/pack/*.idx### Pushing Blobless Clones to New Remotes
A blobless clone cannot be pushed to a new remote without first fetching all blobs:
# This will fail
git remote add newremote https://github.com/other/repo.git
git push newremote main
# fatal: missing blob object...
# Fix: fetch all blobs first
git fetch origin --filter=blob:none --all
git push newremote main### Performance Impact of On-Demand Fetching
On-demand fetching can be slow because objects are fetched one at a time. Git attempts to batch requests for operations like checkout:
# Enable fetch negotiation debugging
GIT_TRACE_PACKET=1 git checkout main
# Check fetch statistics
git count-objects -vSome operations like git blame may be very slow as they fetch many individual blobs. Consider using git backfill first for history-intensive operations.
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