★ Reading this for free? Get 20 structured AI courses + per-chapter AI tutor — the first chapter of every course free, no card.Start free in 30 seconds
Ollama

Ollama Digest Mismatch Error: Delete One Bad Blob

August 23, 2026
12 min read
Local AI Master Research Team

Want to go deeper than this article?

Free account unlocks the first chapter of all 25 courses — RAG, agents, MCP, voice AI, MLOps, real GitHub repos.

📚AI Learning Path

Ollama’s running. Here’s what to build with it. Go from “ollama run” to RAG apps, agents, and fine-tuned models — structured and hands-on. First chapter free.

Start free
Or own it for life — Lifetime $149, pay once

Delete the single blob named after the want digest, then pull again. The error prints want sha256:abc123…; the file is at <models>/blobs/sha256-abc123… — same string, colon swapped for a hyphen. That is the whole mapping, and it means you never need to wipe the blobs directory. The reason retrying alone so often changes nothing is that downloadBlob() in server/download.go treats any file already sitting at the blob path as a cache hit — it calls os.Stat and nothing else — which then sets skipVerify for that layer, so the corrupt file is neither re-hashed nor replaced. Remove the file, and the next pull has to fetch it for real.

Deleting the blob is the mechanical fix. It is not the whole answer, because something produced those wrong bytes and it will do it again. The rest of this page is the diagnosis: one question — does the got digest change between attempts? — splits every report on the tracker into two groups with completely different causes, and the rest follows from that.

This is a different failure from a pull that hangs, crawls or dies mid-transfer. If your download never finished in the first place, you want Ollama pull stuck or slow instead; that page covers resume semantics, the stall watchdog and proxy setup. Come back here only when the bytes all arrived and the hash at the end was wrong.

Every code excerpt, error string and constant below was read from ollama/ollama on main (current release v0.32.15, 19 August 2026) or quoted from the linked issue where a user pasted it. Nothing here is a benchmark and nothing here was invented.

What does digest mismatch, file must be downloaded again actually mean?

It means Ollama finished downloading a layer, hashed the file on disk, and got a different sha256 than the manifest promised. The wording is a single package-level error in server/images.go:

var errDigestMismatch = errors.New("digest mismatch, file must be downloaded again")

func verifyBlob(digest string) error {
	fp, err := manifest.BlobsPath(digest)
	...
	fileDigest, _ := GetSHA256Digest(f)
	if digest != fileDigest {
		return fmt.Errorf("%w: want %s, got %s", errDigestMismatch, digest, fileDigest)
	}
	return nil
}

So the string you see is that sentence plus : want <expected>, got <actual>. It always arrives immediately after the CLI prints verifying sha256 digest, which is the progress status emitted just before the verification loop runs.

Issue #941 is the oldest example still open — opened 28 October 2023, and the report is one paragraph long:

verifying sha256 digest

Error: digest mismatch, file must be downloaded again: want sha256:1a640cd4d69a5260bcc807a531f82ddb3890ebf49bc2a323e60a9290547135c1, got sha256:5eef5d8ec5ce977b74f91524c0002f9a7adeb61606cdbdad6460e25d58d0f454

Two things follow from the code that are worth stating plainly. First, this is Ollama catching a problem, not causing one. A content-addressed store that refuses a file whose hash is wrong is working correctly; the alternative is a model that loads and produces garbage. Second, the check is a re-read from disk, not a check of what came off the wire — which is why a small number of these turn out to be a storage fault rather than a download fault.

Reading articles is good. Building is better.

Free account = 20+ free chapters across 25 courses, with a per-chapter AI tutor. No card. Cancel anytime if you ever upgrade.

Which file do I delete?

Take the digest after want, replace the colon with a hyphen, and look for that filename in the blobs directory. That is not a heuristic; it is literally what manifest.BlobsPath() does:

func BlobsPath(digest string) (string, error) {
	// only accept actual sha256 digests
	pattern := "^sha256[:-][0-9a-fA-F]{64}$"
	...
	digest = strings.ReplaceAll(digest, ":", "-")
	path := filepath.Join(envconfig.Models(), "blobs", digest)
	...
}

The models directory itself depends on how Ollama was installed. These are the paths from the official FAQ:

OS / installModels directoryBlobs live in
macOS~/.ollama/models~/.ollama/models/blobs
Linux, official install script/usr/share/ollama/.ollama/models/usr/share/ollama/.ollama/models/blobs
Linux, run as your own user~/.ollama/models~/.ollama/models/blobs
WindowsC:\Users\%username%\.ollama\models…\.ollama\models\blobs
DockerWhatever you mounted at /root/.ollama/root/.ollama/models/blobs

If you moved the directory with OLLAMA_MODELS and are not certain the server agrees with you about where it is, that is a separate failure with its own per-platform traps — see OLLAMA_MODELS not working before you go hunting for files that are not there.

So for an error reading want sha256:4824460d29f2058aaf6e1118a63a7a197a09bed509f0e7d4e2efb1ee273b447d (that is the real digest from issue #8105, a 42GB llama3.3 pull), the file is:

# macOS, or Linux running as your own user
rm ~/.ollama/models/blobs/sha256-4824460d29f2058aaf6e1118a63a7a197a09bed509f0e7d4e2efb1ee273b447d

# Linux, installed with the official script
sudo rm /usr/share/ollama/.ollama/models/blobs/sha256-4824460d29f2058aaf6e1118a63a7a197a09bed509f0e7d4e2efb1ee273b447d
# Windows PowerShell
Remove-Item "$env:USERPROFILE\.ollama\models\blobs\sha256-4824460d29f2058aaf6e1118a63a7a197a09bed509f0e7d4e2efb1ee273b447d"

Do not rm -rf the blobs directory. Blobs are shared across models — the template, params, license and config layers are tiny files that many models reference, and a large model file you already have is a multi-gigabyte download you would be throwing away for no reason. Deleting one 42GB blob costs you 42GB; deleting the directory can cost you hundreds.

How the blob store is laid out

The store is content-addressed: every filename is the sha256 of that file's contents, and manifests/ holds the JSON that says which blobs make up which model. A real manifest, from ~/.ollama/models/manifests/registry.ollama.ai/library/gemma3/270m:

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
  "config": {
    "mediaType": "application/vnd.docker.container.image.v1+json",
    "digest": "sha256:74156d92caf6d17ac05e9ad7b3eab0a2123f6bce4150f715ebd92e0c3af6cad1",
    "size": 490
  },
  "layers": [
    {
      "mediaType": "application/vnd.ollama.image.model",
      "digest": "sha256:735af2139dc652bf01112746474883d79a52fa1c19038265d363e3d42556f7a2",
      "size": 291545472
    },
    {
      "mediaType": "application/vnd.ollama.image.template",
      "digest": "sha256:4b19ac7dd2fb1ab2f2818b73454c5a9128ca39875a8fcf686a6b1c36100a0d68",
      "size": 476
    },
    {
      "mediaType": "application/vnd.ollama.image.license",
      "digest": "sha256:3e2c24001f9ef57bf7ec959a3658fbb49cdad113cdf394c264da9d16f9bdd132",
      "size": 8431
    },
    {
      "mediaType": "application/vnd.ollama.image.params",
      "digest": "sha256:339e884a40f6708bc761d367f0c08e448d5bb6f16b3961c340e44e0e4835a004",
      "size": 61
    }
  ]
}

That single model is five files in blobs/, only one of which is the weights. You can confirm the naming rule on any model you have pulled, and you should, because it is the check that tells you whether a blob is good without re-pulling anything:

$ shasum -a 256 ~/.ollama/models/blobs/sha256-339e884a40f6708bc761d367f0c08e448d5bb6f16b3961c340e44e0e4835a004
339e884a40f6708bc761d367f0c08e448d5bb6f16b3961c340e44e0e4835a004  ...

Filename in, identical hash out. On Linux the command is sha256sum; in PowerShell it is Get-FileHash -Algorithm SHA256. Anything that does not match is a corrupt blob, whatever ollama list says about it.

Finding the model a bad digest belongs to

The error gives you a digest, not a model name, which is unhelpful when you have twenty models installed. Grep the manifests:

grep -rl "4824460d29f2058aaf6e1118a63a7a197a09bed509f0e7d4e2efb1ee273b447d" ~/.ollama/models/manifests/

The path it prints is the model: .../registry.ollama.ai/library/llama3.3/latest. On Windows, Select-String -Path "$env:USERPROFILE\.ollama\models\manifests\*" -Pattern "4824460d29f2" -Recurse does the same job.

Why does re-running the pull keep failing the same way?

Because downloadBlob() decides a blob is already downloaded by checking that a file exists at the path — nothing more. Here is the branch, from server/download.go:

func downloadBlob(ctx context.Context, opts downloadOpts) (cacheHit bool, _ error) {
	...
	fi, err := os.Stat(fp)
	switch {
	case errors.Is(err, os.ErrNotExist):
	case err != nil:
		return false, err
	default:
		opts.fn(api.ProgressResponse{
			Status:    fmt.Sprintf("pulling %s", opts.digest[7:19]),
			Digest:    opts.digest,
			Total:     fi.Size(),
			Completed: fi.Size(),
		})
		return true, nil
	}
	...
}

That true is the cache hit, and PullModel in server/images.go uses it to set skipVerify[layer.Digest], which excludes that layer from the verification loop entirely. So a corrupt file that reached its final blob name is invisible: the pull prints pulling 4824460d29f2… 100%, then verifying sha256 digest, then success, and the bad bytes stay exactly where they are.

Issue #17520 (opened 2 August 2026, open at the time of writing) is the clean demonstration, with a reproducer you can run yourself. Zero a blob in place while keeping its size — the state a stalled write leaves — and then:

  • ollama list still reports the model as healthy, with its normal size and ID.
  • systemctl restart ollama does not repair it.
  • ollama pull re-reports the layer, prints verifying sha256 digest, prints success, and leaves the bad file in place.
  • Only ollama run fails — and the error it produces does not name the model, the blob or the corruption.

The reporter's summary of how they hit it for real: "a VM hang left two blobs zeroed. Four pulls in a row printed success while the model never appeared in ollama list."

The proposed fix, #17537 ("server: verify blob digest before trusting a same-size cache hit"), makes both pull paths hash a candidate blob before trusting it. It states the root cause in one line: both paths "use a filename-as-hash content-addressed blob store, but neither one actually confirmed the filename matched the content before skipping a re-download." It was open and unmerged when this was written. Until it lands, deleting the file yourself is not a workaround — it is the supported way to invalidate a cache entry.

There is one case where Ollama does clean up after itself. When verifyBlob is run and fails, PullModel removes the file:

if err := verifyBlob(layer.Digest); err != nil {
	if errors.Is(err, errDigestMismatch) {
		fp, err := manifest.BlobsPath(layer.Digest)
		...
		if err := os.Remove(fp); err != nil {
			slog.Info(fmt.Sprintf("couldn't remove file with digest mismatch '%s': %v", fp, err))
		}
	}
	return err
}

So if the mismatch happened on a fresh download, the blob is deleted for you and a retry starts clean. If you are seeing the same error over and over anyway, either the removal failed (that couldn't remove file with digest mismatch line will be in the server log — usually a permissions problem on a Linux install where the daemon runs as the ollama user) or the same wrong bytes are arriving every time. Which brings us to the diagnostic that matters.

Does the got digest change between attempts?

This one question does most of the work. Run the pull two or three times, write down the got value each time, and compare.

What you observeWhat it rules inWhat it rules out
got is identical on every attemptSomething between the registry and your disk is transforming the stream the same way each time — a proxy, a range-request failure, a truncationRandom bit-rot, bad RAM, a dying disk. Random faults do not repeat byte-for-byte
got is different on every attemptNon-deterministic corruption: memory, storage, a filesystem or driver in the read pathA deterministic network transform
got is exactly sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855The file is zero bytesEverything else. That value is the sha256 of an empty input

That third row is worth knowing by sight, and you can confirm it in one command rather than taking anyone's word for it:

$ printf '' | shasum -a 256
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  -

Issue #9846 is titled with that exact digest — a Windows user on 0.6.1 whose got was e3b0c442…, with a server log showing POST "/api/pull" returning 200 in 5.76 seconds. A multi-gigabyte model does not download in under six seconds. Nothing was downloaded at all.

Both patterns have a documented mechanism, and they are covered in the two sections below.

Reading articles is good. Building is better.

Free account = 20+ free chapters across 25 courses, with a per-chapter AI tutor. No card. Cancel anytime if you ever upgrade.

What produces a stable wrong digest?

A registry or proxy that ignores the Range header

This is the best-documented cause on the tracker and it explains the "I have tried eleven times and it is always the same hash" reports. Ollama splits every blob into parts — up to sixteen, fetched concurrently — and requests each one with an HTTP Range header. That assumes the server answers 206 Partial Content. If something answers 200 OK with the whole file instead, Ollama writes the leading bytes of the full file at every part's offset, and the result is a file of exactly the right size made of the wrong content — deterministically, every time.

Issue #10267 (opened 14 April 2025, still open) proves it. The reporter tunnelled the pull through a proxy, watched the range requests come back as 200 rather than 206, and then reconstructed the exact corrupt file by hand. Their reproduction: concatenate the first 100,000,000 bytes of the real model file six times, append the first 37,699,456 bytes, hash the result — and get the same digest Ollama reported.

The arithmetic checks out against the numbers in the report. The blob is a 637 MB TinyLlama layer; 6 × 100,000,000 + 37,699,456 = 637,699,456 bytes, which is that 637 MB. Ollama's part sizing is Total / 16 clamped into a 100MB–1000MB window, so 637.7 / 16 ≈ 39.9 MB clamps up to the 100 MB floor, giving six full parts and one short one. Seven parts, seven copies of the file's opening bytes, one perfectly reproducible wrong hash.

What to do: get off whatever is rewriting the response. In practice that means a corporate TLS-inspecting proxy, a captive portal, some VPN concentrators, or an aggressive caching middlebox. Pull from a different network once to confirm — if it succeeds on a phone hotspot and fails on the office LAN, you have your answer and no amount of retrying on the office LAN will help.

A response with no Content-Length

PR #17580 (opened 5 August 2026, unmerged at the time of writing) documents the empty-blob path precisely: blobDownload.Prepare discarded the error from parsing Content-Length, so if a registry — or a proxy in front of one — answers without that header, "b.Total silently becomes 0, so the part-building loop never runs and no parts are created," and then "os.Rename promotes an empty file to the blob path while returning success."

The PR is explicit about why this is worth naming separately: "The empty blob is caught later by verifyBlob, so nothing corrupt gets stored, but the user sees a digest mismatch. That reads like a corrupted or tampered blob when the actual cause is a registry that did not report a size, which sends you looking in entirely the wrong place."

That is the mechanism behind the e3b0c44… signature. Same fix as above: the thing stripping headers is between you and the registry.

The disk filled up mid-write

An interrupted or short write leaves a file of the wrong length or with a zeroed tail. Ollama treats out-of-space as fatal rather than retryable — syscall.ENOSPC is one of only two errors the chunk loop returns immediately on, alongside context.Canceled — so a clean out-of-disk usually surfaces as no space left on device rather than a digest mismatch. But a partially full disk, a quota, a container layer limit or a filesystem that reports space it cannot deliver can all produce a short write that completes without an error.

Check free space against the model size before re-pulling. If a 42GB download is going to land on a partition with 45GB free, you also need room for the temporary -partial file, which is preallocated to the blob's full size before a single byte is written. Our Ollama model RAM and VRAM table lists the on-disk sizes alongside the memory requirements, which is the cheaper thing to check first.

What produces a different wrong digest every time?

Non-deterministic corruption, and it is almost always local. Two reports document it carefully enough to be useful.

Issue #16695 is an 80GB pull that failed three times with three different got digests, laid out in the report as:

Error: digest mismatch, file must be downloaded again:
  want sha256:a46088eccd0d171cc2694f315f2921bd0fda0ae3577099c4864cbe98f190807e
  got  sha256:579e02e55f9a5aa5d58555dfdca243a6e5b340b24952084a0033edb477c4cf5a  (attempt 1)
  got  sha256:6392b4583c9fbb874a811066019b53e58287825f9f71b367d1c2404441bdb11e  (attempt 2)
  got  sha256:979a51453133ccca9f4bb67034b35b579925a89920df3a90f2fcfc6bee4ef5e8  (attempt 3)

PR #15489 chased the same pattern much further, and its findings are the single most useful thing on the tracker for this class of failure. On a machine with a reproducible mismatch, the author confirmed that the bytes on the wire were correct — an inline sha256 tee'd off the HTTP response body during download matched the expected digest, and curl piped to sha256sum against the same URL also matched. The blob was even functional: ollama run on it loaded and generated coherent text. But re-reading the file from disk with sha256sum, with io.Copy(sha256.New(), f) and with several other approaches all returned different wrong hashes on the same system. Their own conclusion: "it's somewhere below ollama and I ran out of ladder."

The practical reading of that is uncomfortable but clear. When got changes every time, the download is probably fine and the read path is not. Things worth eliminating, in the order that costs you least:

  1. Point the models directory at a different disk and pull there. OLLAMA_MODELS=/some/other/disk/models on the server process — not your shell — and re-run. If it verifies on one disk and not another, you are done diagnosing.
  2. Network filesystems. An NFS, SMB, or virtualised-disk models directory is a common factor in these reports. Move it to local storage for the test.
  3. Storage health. SMART data, and on Linux dmesg for I/O errors around the time of the failure.
  4. Memory. Several reporters in this bucket mention that memtest passes, so do not treat a clean memtest as proof, but a failing one ends the investigation immediately.
  5. Overclocks and undervolts, including RAM XMP/EXPO profiles. Hashing 80GB is an unusually thorough stability test and it is not rare for it to be the first workload that fails on a marginal profile.

One current bug makes this class harder to diagnose than it should be. GetSHA256Digest calls log.Fatal(err) if the read fails, and log.Fatal calls os.Exit(1) — so a genuine disk read error while hashing "does not fail the request, it terminates the whole server and drops every other in-flight request with it," per PR #17590 (opened 6 August 2026, unmerged). If your Ollama server vanishes during verifying sha256 digest rather than printing a mismatch, that is what happened, and it is a storage fault rather than a digest problem.

What about ollama create and GGUF imports?

A digest mismatch during ollama create is a different error string from a different file, and it points at your local copy rather than the registry. The import path returns this from server/routes.go:

if layer.Digest != c.Param("digest") {
	c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("digest mismatch, expected %q, got %q", c.Param("digest"), layer.Digest)})
	return
}

Note the shape: expected "sha256:…", got "sha256:…" with quotes, and an HTTP 400 rather than the pull-path wording. If your error says expected/got you are looking at POST /api/blobs/:digest, which is the CLI uploading your local GGUF to the server; if it says want/got you are looking at a registry pull.

Issue #13775 is the instructive one here, partly because of how it ended. The reporter had a 6.7GB GGUF, a sha256sum on disk that matched Hugging Face, and ollama create failing with a different "got" hash on each attempt. A maintainer downloaded the same file, hashed it, hashed the resulting blob, and got the expected digest on both — then asked the reporter to check for memory or disk read errors. The reporter closed it themselves with "i genuinely believe it's not an entry issue with ollama. But i also can't figure out wtf it is." Same signature, same conclusion: a changing got is a local read-path problem, and the fact that sha256sum on the source file passes does not clear the machine, because the copy is a separate read.

The third variant, for completeness: the fast-transfer path used for safetensors models (x/transfer/download.go) returns a bare digest mismatch with no want/got at all, after removing its own .tmp file. If your error has no digests in it, that is the path you are on.

Where does OLLAMA_NOPRUNE fit?

Not where most people put it. OLLAMA_NOPRUNE is a boolean the server reads at startup, described in envconfig/config.go as "Do not prune model blobs on startup." Setting it does not make verification stricter, does not repair anything and does not affect the digest check at all.

What it changes is startup housekeeping. On boot, Serve() runs PruneLayers() unless the variable is set, and that function walks blobs/, converts - back to : in each filename, and removes any file that will not parse as a valid digest — the source comment reads "remove invalid blobs (e.g. partial downloads)" — subject to a one-hour grace period on the file's modification time. Anything left over that no manifest references then gets deleted too.

SituationShould you set OLLAMA_NOPRUNE?
You are resuming an abandoned download from yesterday and want the -partial files keptYes, before starting the server
You are trying to fix a digest mismatchNo. It has no effect on verification
You want Ollama to stop deleting a blob you are inspectingYes, temporarily — then unset it
You are debugging why a blob keeps disappearingYes, so the file survives long enough to hash

There is one adjacent behaviour worth knowing, because it produces a confusing log line. If manifest.Manifests() cannot parse your manifests, the server logs corrupt manifests detected, skipping prune operation. Re-pull or delete to clear and skips the sweep entirely. A truncated or zero-length manifest file — the same VM-hang or disk-full scenario that damages blobs — will do that, and no amount of blob deletion fixes a broken manifest. Delete the offending file under manifests/ and pull the model again.

Which circulating workarounds no longer work?

Search results for this error are old, and two suggestions in circulation are actively wrong on a current build.

OLLAMA_EXPERIMENT=client2 is dead. It was suggested by a maintainer on issue #16695 in June 2026 and it did something then. On main today, the only thing it does is print a warning:

OLLAMA_EXPERIMENT=client2 is no longer available. Please remove this environment.

OLLAMA_REGISTRY_MAXSTREAMS=1 no longer exists. It appeared in the same suggestion, and a search of the current repository returns no occurrences of that name in any file. The nearest surviving relative is OLLAMA_MAX_TRANSFER_STREAMS (default 4), and its own comment in envconfig/config.go scopes it explicitly: it "caps the number of simultaneous body-bearing transfers during safetensors model pulls/pushes" and "has no effect on GGUF transfers, which use the legacy upload/download paths." Setting it will not reduce the parallel range requests that a normal GGUF pull uses.

If reducing parallelism is what you actually want — because you suspect the range-request problem above — there is no supported setting for it. The open PR #15028 proposes validating that chunk responses are 206 or 200 before writing them, verifying the assembled file before the rename, and auto-retrying once on mismatch. It has been open since 23 March 2026 and is unmerged. Do not build a workflow around it.

The fix, in order

  1. Read the error. Note the want digest and the got digest. Keep them.
  2. Delete the one blob named sha256-<want> in your models directory's blobs/ folder. Not the directory.
  3. Pull again, and record the new got if it fails.
  4. Compare the two got values. Identical means the wire; different means the machine; e3b0c44… means an empty file.
  5. If it is the wire: pull once from a completely different network. If that works, fix or bypass the proxy, VPN or middlebox — see the proxy section of our Ollama pull troubleshooting guide for where HTTPS_PROXY has to be set for each install type.
  6. If it is the machine: move the models directory to a different local disk with OLLAMA_MODELS and retry there before you touch anything else.
  7. If the blob verifies by hand but run still fails, you are no longer debugging a digest mismatch — go to Ollama 500 Internal Server Error and read the server log.

Honest limitations

  • Nothing here was reproduced on a machine we deliberately broke. The code is quoted from ollama/ollama on main; every error string and log line is from the linked issue where a user pasted it. The blob-store layout, the manifest above and the shasum output are from a normal Ollama install with models already pulled — they show structure, not performance, and there are no benchmarks on this page because none were run.
  • #941, #8105, #9846, #10267, #16695 and #17520 were open and PRs #15028, #15489, #17537, #17580 and #17590 were unmerged when this was written. Click through before assuming a workaround is still needed.
  • Source drifts. downloadBlob, verifyBlob and PruneLayers are accurate for main at v0.32.15 (19 August 2026). If #17537 merges, the cache-hit behaviour described above changes and deleting the blob by hand stops being necessary.
  • We cannot tell you which of the two buckets you are in without your two got values. That is the whole reason step 3 exists, and it is not a formality — the fixes on either side share nothing.
  • A registry-side bad file is possible but rare, and hard to distinguish from a proxy. If a specific model fails identically for you on two unrelated networks and two machines, say so on the tracker with both digests rather than assuming it is your hardware.

FAQ

What does "digest mismatch, file must be downloaded again" mean in Ollama?

The downloaded layer's sha256 does not match the digest the model manifest promised. Ollama hashes each blob after downloading it and refuses any file whose contents do not match its own filename, because the blob store is content-addressed. The full string includes both values — want is what the manifest expects, got is what your file actually hashes to.

How do I delete just the corrupt blob instead of everything?

Take the digest after want, swap the colon for a hyphen, and delete that filename from the blobs folder inside your models directory — ~/.ollama/models/blobs/sha256-abc123… on macOS, /usr/share/ollama/.ollama/models/blobs/ on a standard Linux install. Blobs are shared between models, so wiping the directory throws away downloads that were never broken.

Why does re-running ollama pull not fix a digest mismatch?

Because downloadBlob() calls os.Stat on the blob path and treats any existing file as a cache hit, which then skips verification for that layer. A corrupt file that reached its final name is neither re-hashed nor replaced, so the pull can print success with the bad bytes still in place. Issue #17520 documents this and PR #17537 proposes hashing cache hits before trusting them; it was unmerged at the time of writing.

What does it mean if got is sha256:e3b0c442…?

Your file is zero bytes. e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 is the sha256 of an empty input, which you can confirm with printf '' | shasum -a 256. PR #17580 traces one route to it: a registry or proxy that answers without a Content-Length header causes Ollama to build zero download parts and then rename an empty file into place.

The got hash is different every time I retry. What does that mean?

Non-deterministic corruption, which is almost always local rather than on the network — a network transform would repeat byte-for-byte. PR #15489 traced one such case and found the bytes arriving over HTTP were correct while re-reading the same file from disk produced a different wrong hash each time. Move the models directory to a different local disk with OLLAMA_MODELS and retry there before investigating anything else.

Does OLLAMA_NOPRUNE help with digest mismatch?

No. It only disables the startup sweep that removes partial downloads and unreferenced blobs, and it has no effect on digest verification. It is useful when you want a half-finished download or a blob you are inspecting to survive a server restart, not when you want a corrupt one repaired.

My error says "expected" and "got" instead of "want" and "got". Is that different?

Yes. digest mismatch, expected "…", got "…" comes from POST /api/blobs/:digest — the import path used by ollama create when the CLI uploads a local GGUF to the server — and returns HTTP 400. The registry pull path uses want. A mismatch on the import path means the bytes changed between your file and the server's copy of it, so check the disk and memory on the machine doing the copy, not your network.

Is a digest mismatch ever the registry's fault?

Occasionally, but it is the last hypothesis rather than the first, because a proxy that rewrites responses looks identical from your side. The test that separates them: pull the same model on a different network and, ideally, a different machine. If both fail with the same got digest, report it on the tracker with both values — that is genuinely useful evidence. If one succeeds, the problem was on the path that failed.

Sources

🎯
AI Learning Path

Ollama’s running. Here’s what to build with it.

Go from “ollama run” to RAG apps, agents, and fine-tuned models — structured and hands-on. First chapter free.

Or own it for life — Lifetime $149 $599, pay once
Once your hardware is sorted

Stop piecing Ollama together from blog posts

Ollama Mastery is 15 chapters end to end — install, model choice, Modelfiles, GPU offload, the API, and the 20 errors that actually happen. Plus 24 more courses.

$149 once unlocks everything, forever — about $0.27/chapter for life. Prefer to spread it out? Pro is $79/year (saves 27%) or $8.99/month.
Secure checkout by Lemon Squeezy — your card never touches this siteInstant access the moment you payFirst chapter of every course is free — try before you buy

Liked this? 20 full AI courses are waiting.

From fundamentals to RAG, agents, MCP servers, voice AI, and production deployment with real GitHub repos. First chapter free, every course.

Reading now
Join the discussion

Local AI Master Research Team

Creator of Local AI Master. I've built datasets with over 77,000 examples and trained AI models from scratch. Now I help people achieve AI independence through local AI mastery.

Build Real AI on Your Machine

RAG, agents, NLP, vision, and MLOps - chapters across 25 courses that take you from reading about AI to building AI.

Want structured AI education?

25 courses, 519+ chapters, from $9. Understand AI, don't just use it.

AI Learning Path
More on Ollama
See the full Best Ollama Models 2026 guide.

Comments (0)

No comments yet. Be the first to share your thoughts!

📅 Published: August 23, 2026🔄 Last Updated: August 23, 2026✓ Manually Reviewed

Ready to Go Beyond Tutorials?

20 structured courses with hands-on chapters - build RAG chatbots, AI agents, and ML pipelines on your own hardware.

🎯
AI Learning Path

Go from reading about AI to building with AI

20 structured courses. Hands-on projects. Runs on your machine. Start free.

Or own it for life — Lifetime $149 $599, pay once

Was this helpful?

LM

Written by the Local AI Master Team

The team behind Local AI Master

We build Local AI Master around practical, testable local AI workflows: model selection, hardware planning, RAG systems, agents, and MLOps. The goal is to turn scattered tutorials into a structured learning path you can follow on your own hardware.

✓ Local AI Curriculum✓ Hands-On Projects✓ Open Source Contributor
📚
Free · no account required

Grab the AI Starter Kit — career roadmap, cheat sheet, setup guide

No spam. Unsubscribe with one click.

🎯
AI Learning Path

Ollama’s running. Here’s what to build with it.

Go from “ollama run” to RAG apps, agents, and fine-tuned models — structured and hands-on. First chapter free.

Or own it for life — Lifetime $149 $599, pay once
Free Tools & Calculators