[PR #15018] [CLOSED] fix: preserve partial download files during PruneLayers #40843

Closed
opened 2026-04-23 01:38:40 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/ollama/ollama/pull/15018
Author: @jasonkwh
Created: 3/23/2026
Status: Closed

Base: mainHead: fix/preserve-partial-downloads-on-prune


📝 Commits (1)

  • 3fef6b9 fix: preserve partial download files during PruneLayers

📊 Changes

1 file changed (+6 additions, -1 deletions)

View changed files

📝 server/images.go (+6 -1)

📄 Description

Problem

When pulling a large model on an unstable connection (e.g. a mobile hotspot), downloads would always restart from 0% after a server restart instead of resuming from where they left off. This was extremely frustrating — a 4GB model interrupted at 80% would have to start over completely after reconnecting.

Root Cause

PruneLayers runs on every server startup to clean up orphaned blobs. It identifies "invalid" files by replacing - with : in filenames and checking against the sha256 digest regex ^sha256[:-][0-9a-fA-F]{64}$.
In-progress partial download files are named:

  • sha256-<digest>-partial — the raw bytes being written
  • sha256-<digest>-partial-0, -partial-1, ... — JSON metadata tracking progress per part
    After the -: substitution, these become sha256:<digest>:partial and sha256:<digest>:partial:0, which fail the regex. The code even had a comment acknowledging this: // remove invalid blobs (e.g. partial downloads) — but that was the wrong behaviour. These files are intentionally left on disk by run() so that Prepare() can restore progress on the next pull attempt.
    The result: every server restart wiped all partial download state, making the resume mechanism in download_types.go completely ineffective in practice.

Fix

Skip files containing -partial in PruneLayers. They are cleaned up naturally by run() upon successful download completion (metadata files are deleted, the data file is renamed to the final digest path). If a download never completes, the files remain available for Prepare() to resume from on the next ollama pull.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/ollama/ollama/pull/15018 **Author:** [@jasonkwh](https://github.com/jasonkwh) **Created:** 3/23/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/preserve-partial-downloads-on-prune` --- ### 📝 Commits (1) - [`3fef6b9`](https://github.com/ollama/ollama/commit/3fef6b98eb2fd0711169844aec1028104571d9a0) fix: preserve partial download files during PruneLayers ### 📊 Changes **1 file changed** (+6 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `server/images.go` (+6 -1) </details> ### 📄 Description ## Problem When pulling a large model on an unstable connection (e.g. a mobile hotspot), downloads would always restart from 0% after a server restart instead of resuming from where they left off. This was extremely frustrating — a 4GB model interrupted at 80% would have to start over completely after reconnecting. ## Root Cause `PruneLayers` runs on every server startup to clean up orphaned blobs. It identifies "invalid" files by replacing `-` with `:` in filenames and checking against the sha256 digest regex `^sha256[:-][0-9a-fA-F]{64}$`. In-progress partial download files are named: - `sha256-<digest>-partial` — the raw bytes being written - `sha256-<digest>-partial-0`, `-partial-1`, ... — JSON metadata tracking progress per part After the `-` → `:` substitution, these become `sha256:<digest>:partial` and `sha256:<digest>:partial:0`, which fail the regex. The code even had a comment acknowledging this: `// remove invalid blobs (e.g. partial downloads)` — but that was the wrong behaviour. These files are intentionally left on disk by `run()` so that `Prepare()` can restore progress on the next pull attempt. The result: every server restart wiped all partial download state, making the resume mechanism in `download_types.go` completely ineffective in practice. ## Fix Skip files containing `-partial` in `PruneLayers`. They are cleaned up naturally by `run()` upon successful download completion (metadata files are deleted, the data file is renamed to the final digest path). If a download never completes, the files remain available for `Prepare()` to resume from on the next `ollama pull`. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-23 01:38:40 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/ollama#40843