Git LFS fails to download large-file objects during checkout or clone. Common causes are missing objects on the server, expired credentials, or network problems.
The "Smudge error: Error downloading object" in Git LFS means the smudge filter failed to replace a pointer file with the actual large-file content. Git LFS stores large files as small text "pointer" files in Git history, and a "smudge" filter swaps each pointer for its real binary content when you check files out. When you clone a repository or check out a branch, Git LFS intercepts the working-tree write and downloads the real content from the LFS server. If that download fails, you get a smudge error. The message usually includes the specific URL that returned an error and the HTTP status code, which tells you whether the problem is authentication (401/403), a missing object (404), or network/server trouble (timeouts, 5xx). The underlying cause is typically that the LFS object was never pushed to the server, your credentials are invalid or expired, the LFS server is unreachable, or a proxy/firewall is blocking the transfer. The object ID (an `oid sha256:` hash) in the error identifies exactly which file failed.
The most reliable approach is to clone without running the smudge filter, then download the LFS objects in one batch where failures can be retried.
# Tell LFS to skip the smudge filter for new clones
git lfs install --skip-smudge
# Clone the repository (working tree gets pointer files only)
git clone <repository-url>
cd <repository-name>
# Download all LFS objects and populate the working tree
git lfs pull
# Re-enable the smudge filter for normal future operations
git lfs installNote: git lfs install (no flags) re-enables smudge by rewriting the filter config. Do not use --force for this — --force only overwrites existing hooks and does not control the skip-smudge setting.
You can achieve the same effect for a single clone with the environment variable GIT_LFS_SKIP_SMUDGE=1 git clone <url>, which is especially handy in CI.
If the repository is already cloned and pull/checkout fails on LFS files, temporarily relax the filter, fetch the objects, then restore the filter.
# Temporarily disable the smudge step and make LFS non-required
git config --local filter.lfs.smudge "git-lfs smudge --skip -- %f"
git config --local filter.lfs.process "git-lfs filter-process --skip"
git config --local filter.lfs.required false
# Update Git history (working tree gets pointer files)
git pull --rebase --autostash
# Download all LFS objects
git lfs fetch --all
# Populate the working tree from the downloaded objects
git lfs checkout
# Restore the normal filter configuration
git config --local filter.lfs.smudge "git-lfs smudge -- %f"
git config --local filter.lfs.process "git-lfs filter-process"
git config --local filter.lfs.required trueResetting filter.lfs.process matters because modern Git LFS uses the long-running process filter, not just the per-file smudge filter.
Authentication failures (HTTP 401/403) are a frequent cause. Inspect the environment and credentials.
# Show the resolved LFS environment, including the endpoint
git lfs env
# Show the configured LFS endpoint
git config --get lfs.urlFor GitHub:
# Confirm you are authenticated
gh auth status
# If you cloned over SSH, LFS still uses HTTPS by default; point it explicitly if needed
git config lfs.url https://github.com/<owner>/<repo>.git/info/lfsWith a Personal Access Token, use a credential helper so the token is stored securely rather than typed repeatedly. On macOS/Windows prefer the OS keychain; on Linux use libsecret:
# Linux (libsecret), recommended over plaintext storage
git config --global credential.helper libsecret
# Then trigger a fetch; you'll be prompted for username + token once
git lfs fetchAvoid credential.helper store, which writes the token in plaintext to ~/.git-credentials. Use it only as a last resort on a trusted, single-user machine.
For Bitbucket (duplicate Authorization header issue), keep Git on SSH but pin LFS to HTTPS:
git config lfs.url https://bitbucket.org/<workspace>/<repo>.git/info/lfsA 404 means the object does not exist on the server — it was never pushed or was lost during a migration.
# List LFS files referenced across all history
git lfs ls-files --all | head -20If you (or a teammate) still have a local copy with the real files, push the objects to the server:
# Push every LFS object reachable from all refs
git lfs push --all originNote: git lfs push does not take an --object-id flag. To push the objects for a specific ref, use git lfs push origin <branch>; to push everything use --all.
If no one has the original files:
1. Check whether another team member or a CI cache has a complete clone.
2. Look for backups or older clones that still hold the objects under .git/lfs/objects.
3. Identify the commits that introduced the file so you understand the impact:
git log --all --full-history -- <path-to-file>4. As a last resort, replace the missing file with a documented placeholder and commit it, noting the object is permanently lost.
For flaky networks, reduce concurrency, raise retries, and extend timeouts.
# Lower concurrent transfers (default is 8)
git config --global lfs.concurrenttransfers 3
# Increase the number of retry attempts
git config --global lfs.transfer.maxretries 10
# Allow longer idle and TLS handshake times (seconds)
git config --global lfs.activitytimeout 60
git config --global lfs.tlstimeout 60Behind a corporate proxy:
git config --global http.proxy http://proxy.company.com:8080
git config --global https.proxy http://proxy.company.com:8080
# Or scope the proxy to a single host
git config --global http.https://lfs-server.com.proxy http://proxy.company.com:8080Do NOT disable TLS verification (http.sslVerify false) to work around certificate errors — that exposes your credentials and downloads to interception. Instead, install the correct CA certificate and point Git at it:
git config --global http.sslCAInfo /path/to/corporate-ca.pemOnly if you fully understand the risk and are on a throwaway, isolated machine should you ever temporarily set http.sslVerify false, and you should re-enable it immediately afterward.
If LFS hooks or filters are broken, reinstall them cleanly. This only touches configuration and hooks, not your downloaded objects.
# Remove LFS hooks and filter config
git lfs uninstall
# Reinstall LFS hooks and filters
git lfs install
# Confirm the resulting configuration
git lfs envCheck that .gitattributes actually routes your file types through LFS:
cat .gitattributesYou should see entries such as:
*.psd filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -textIf the primary LFS server is down or the repo was migrated, you may be able to pull objects from another source.
# Add an alternative remote (for example an upstream fork)
git remote add upstream https://github.com/<original-owner>/<repo>.git
# Fetch LFS objects from that remote
git lfs fetch upstream --allFor a repository that was migrated between servers, fetch from the old server, then push to the new one:
# Point LFS at the old server and pull every object
git config lfs.url https://old-server.com/repo.git/info/lfs
git lfs fetch --all
# Point LFS back at the new server and push the objects
git config lfs.url https://new-server.com/repo.git/info/lfs
git lfs push --all origin
# Optionally clear the override so the default endpoint is used
git config --unset lfs.urlVerify that locally stored LFS objects are present and not corrupted before assuming the server is at fault.
# Show the LFS status of changed files
git lfs status
# Verify the integrity of local LFS objects
git lfs fsck
# Preview which unreferenced objects pruning would remove
git lfs prune --dry-runIf git lfs fsck reports corruption, do NOT blindly delete the local object cache. The cache may hold objects that have never been pushed to the server, and those are unrecoverable once deleted.
First, guarantee the server has a copy of everything:
# Confirm every local object is also on the server
git lfs push --all originIf that command succeeds, the server holds all objects and re-downloading is safe. Then remove only the corrupted objects (or, if you must, the whole cache) and re-fetch:
# Safer: prune only verified, server-backed objects
git lfs prune
# Then re-download
git lfs fetch --allOnly wipe the entire cache with rm -rf .git/lfs/objects after the git lfs push --all above has confirmed the server has every object — otherwise you risk permanently losing data that exists nowhere else.
To inspect a single pointer or confirm an object exists on disk:
git lfs pointer --file <path-to-file>
ls -la .git/lfs/objects/<first-2-chars>/<next-2-chars>/Smudge and clean filters: Git LFS installs two filters. The *clean* filter converts large files into pointer files when you stage with git add; the *smudge* filter converts pointers back into real content on checkout. Modern Git LFS actually uses a single long-running *process* filter (git-lfs filter-process) that handles both directions for efficiency, which is why filter.lfs.process must also be set correctly.
LFS pointer file format:
version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 12345Debugging: Enable verbose tracing to see the exact request and server response:
GIT_TRACE=1 GIT_TRANSFER_TRACE=1 GIT_CURL_VERBOSE=1 git lfs pullBe aware that GIT_CURL_VERBOSE=1 can print Authorization headers — scrub logs before sharing them.
Windows-specific: Line-ending rewriting can corrupt pointer files, so set git config core.autocrlf false (or use -text in .gitattributes, which LFS adds automatically) for LFS-tracked binaries.
CI/CD:
- Many runners need LFS explicitly enabled before checkout.
- GitHub Actions: set lfs: true on actions/checkout.
- GitLab CI: set GIT_LFS_SKIP_SMUDGE: "1", then run git lfs pull after checkout so failed downloads can be retried in one step.
Self-hosted LFS servers: confirm valid TLS certificates, adequate storage and bandwidth, correctly configured authentication, and check the server logs for the underlying cause behind a generic client-side error.
ssh: Could not resolve hostname github.com: Name or service not known
How to fix 'ssh: Could not resolve hostname github.com: Name or service not known' in Git
error: insufficient permission for adding an object to repository database .git/objects
How to fix "insufficient permission for adding an object to repository database" in Git
fatal: could not create work tree dir 'repo': Permission denied
How to fix "could not create work tree dir: Permission denied" in Git
fetch-pack: unexpected disconnect while reading sideband packet
How to fix 'unexpected disconnect while reading sideband packet' in Git
error: multi-pack-index verification failed
How to fix 'multi-pack-index verification failed' error in Git