Partial clones reduce download size by filtering objects, but they require server support and can fail when fetching filtered objects later.
The Error
Attempting partial clone:
git clone --filter=blob:none https://github.com/user/repo.gitYou see:
fatal: filter 'blob:none' not supported by remote
fatal: remote error: filter not supportedOr later fetching missing objects:
git checkout HEAD~10fatal: unable to read blob abc1234567890
fatal: object not found - perhaps a partial clone?
error: object filter spurious filterOr:
fatal: promisor remote 'origin' returned unexpected object type
fatal: remote error: upload-pack: expected object, got errorWhy Partial Clones Fail
Common causes:
- Server doesn't support filters - Git server must implement filter capability
- Wrong filter syntax - Filter specification is malformed
- Promisor remote unavailable - Remote needed for missing objects
- Network issues during lazy fetch - Object fetch interrupted
- Object corruption - Partial data corrupted
- Remote configuration issues - Promisor remote misconfigured
Diagnosis Steps
Check server capabilities:
``bash
git ls-remote --symref https://github.com/user/repo.git HEAD
Look for filter in capabilities:
``bash
GIT_TRACE=1 git clone --filter=blob:none <url> 2>&1 | grep filter
Check if clone is partial:
``bash
git config --get remote.origin.promisor
git config --get remote.origin.partialclonefilter
Check missing objects:
``bash
git fsck --full
May show:
``
missing blob abc123...
error: could not fetch missing objects from promisor remote
Check promisor configuration:
``bash
git config --list --local | grep promisor
git config --list --local | grep partialclone
Solution 1: Verify Server Supports Partial Clone
Check server capabilities:
GIT_TRACE_PACKET=1 git ls-remote <url> 2>&1 | grep fetch-filterIf no output, server doesn't support partial clones.
Servers that support partial clone: - GitHub.com - GitLab.com (since 13.1) - Azure DevOps (limited) - Bitbucket Server (some versions)
Servers that may not support: - Older Git servers (< 2.22) - Gerrit (depends on version) - Self-hosted Git without partial clone config
Solution 2: Use Supported Filter Type
Try different filter options:
```bash # Blobless - no file contents initially git clone --filter=blob:none <url>
# Treeless - no trees initially git clone --filter=tree:none <url>
# Size limit - blobs under size git clone --filter=blob:limit=1m <url>
# Depth combined with filter git clone --filter=blob:none --depth=100 <url> ```
Solution 3: Fetch Missing Objects Manually
When lazy fetch fails:
git fetch origin --filter=blob:noneOr fetch specific missing objects:
``bash
# Get missing blob hash from error
git fetch origin abc1234567890
Or force fetch all blobs:
``bash
git fetch origin --filter=blob:none --no-filter
Solution 4: Convert Partial to Full Clone
When partial clone causes too many issues:
# Fetch all missing objects
git fetch --unshallow --filter=blob:none 2>/dev/null || git fetch originRemove partial clone configuration:
``bash
git config --unset remote.origin.promisor
git config --unset remote.origin.partialclonefilter
Fetch everything:
``bash
git fetch origin
git checkout HEAD
Solution 5: Fix Promisor Remote Configuration
If promisor remote is misconfigured:
# Check current promisor settings
git config --get remote.origin.promisor
git config --get remote.origin.partialclonefilter
git config --get remote.origin.urlReset promisor configuration:
``bash
git config remote.origin.promisor true
git config remote.origin.partialclonefilter blob:none
Add backup promisor remote:
``bash
git remote add backup <backup-url>
git config remote.backup.promisor true
git config remote.backup.partialclonefilter blob:none
Solution 6: Handle Filter Specification Errors
Invalid filter syntax:
fatal: invalid filter-spec 'blob:none '
fatal: remote error: invalid filterCorrect filter syntax:
``bash
git clone --filter=blob:none <url> # No trailing space
git clone --filter=blob:limit=1m <url> # Correct size format
Solution 7: Fix Network Issues During Lazy Fetch
When lazy fetch fails due to network:
fatal: unable to access 'https://github.com/user/repo.git/': Failed to connect
fatal: lazy fetch failed for path 'src/file.js'Retry the fetch:
``bash
git fetch origin
git checkout HEAD -- src/file.js
Or prefetch common paths:
``bash
git checkout HEAD
git checkout HEAD~10 -- src/
Increase timeout:
``bash
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999
Solution 8: Handle Object Type Errors
Promisor returns unexpected type:
fatal: promisor remote returned unexpected object typeRefresh from remote:
``bash
git fetch origin --prune
git checkout HEAD --force
Verify object:
``bash
git cat-file -t abc123456
Solution 9: Reclone as Full Repository
When partial clone is too problematic:
```bash # Backup current state git stash push -m "saving partial clone work" git branch backup-branch
# Clone fresh without filter git clone <url> repo-full cd repo-full
# Restore work git stash pop # Copy stash from old repo first ```
Verification
Verify partial clone status:
``bash
git config --get remote.origin.promisor
Should return true for partial clone.
Test object fetching works:
``bash
git checkout HEAD~20
git status
Should successfully lazy-fetch needed objects.
Check all objects accessible:
``bash
git rev-list --all --objects | head -100
All objects should be accessible without errors.
Verify filter is applied:
``bash
git count-objects -v
Shows fewer objects than full clone would have.
Partial Clone Options Reference
```bash # Blobless - most common, lazy loads file contents git clone --filter=blob:none <url>
# Treeless - even more minimal, lazy loads trees git clone --filter=tree:none <url>
# Size threshold - exclude large blobs git clone --filter=blob:limit=<size> <url>
# Combine with shallow git clone --filter=blob:none --depth=100 <url>
# Combine with single branch git clone --filter=blob:none --single-branch <url> ```
Comparison: Partial Clone vs Shallow Clone
| Feature | Partial Clone | Shallow Clone |
|---|---|---|
| History depth | Full history | Limited depth |
| File contents | Lazy loaded | All included |
| Merge support | Yes | Limited |
| History browsing | Yes | Limited depth |
| Disk space | Small initially | Fixed small |
| Server support | Required | Universal |
Best Practices
Use blob:none for large repos:
``bash
git clone --filter=blob:none https://github.com/large-org/large-repo.git
Reduces initial clone dramatically.
Prefetch likely-needed objects:
``bash
git fetch origin --filter=blob:none --depth=1000
Gets history with blobs for recent commits.
Configure good network:
``bash
git config --global http.postBuffer 524288000
Large buffer for fetching missing objects.
Don't use partial clone for: - Offline work - Archival purposes - CI that needs all files - Servers without support
Server Configuration for Partial Clone
For self-hosted Git servers, enable filter support:
Git daemon:
``bash
git daemon --enable=upload-pack.filter
Git over SSH: Ensure server Git version >= 2.22.
GitLab: Partial clone supported since 13.1, enabled by default.
Gerrit:
``bash
# In gerrit.config
[receive]
enablePartialClone = true