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:

bash
git clone --filter=blob:none https://github.com/user/repo.git

You see:

bash
fatal: filter 'blob:none' not supported by remote
fatal: remote error: filter not supported

Or later fetching missing objects:

bash
git checkout HEAD~10
bash
fatal: unable to read blob abc1234567890
fatal: object not found - perhaps a partial clone?
error: object filter spurious filter

Or:

bash
fatal: promisor remote 'origin' returned unexpected object type
fatal: remote error: upload-pack: expected object, got error

Why 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:

bash
GIT_TRACE_PACKET=1 git ls-remote <url> 2>&1 | grep fetch-filter

If 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:

bash
git fetch origin --filter=blob:none

Or 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:

bash
# Fetch all missing objects
git fetch --unshallow --filter=blob:none 2>/dev/null || git fetch origin

Remove 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:

bash
# Check current promisor settings
git config --get remote.origin.promisor
git config --get remote.origin.partialclonefilter
git config --get remote.origin.url

Reset 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:

bash
fatal: invalid filter-spec 'blob:none '
fatal: remote error: invalid filter

Correct 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:

bash
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:

bash
fatal: promisor remote returned unexpected object type

Refresh 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

FeaturePartial CloneShallow Clone
History depthFull historyLimited depth
File contentsLazy loadedAll included
Merge supportYesLimited
History browsingYesLimited depth
Disk spaceSmall initiallyFixed small
Server supportRequiredUniversal

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