Devolutions/UniGetUI · error · InvalidDataException
The updater download server returned an invalid partial cont
Error message
The updater download server returned an invalid partial content range.
What it means
DownloadInstallerPartAsync requests a Range resume when a valid partial file and metadata exist. If the server responds with HTTP 206 Partial Content, IsValidPartialResponse checks that the Content-Range header's From value equals the current partialLength. When it does not, the engine normally deletes the partial and restarts (allowRestart=true). The InvalidDataException is only thrown on the recursive call where allowRestart is false — meaning the server returned a bad range twice in a row. This signals a genuinely broken CDN/mirror or a corrupted partial that cannot be trusted.
Source
Thrown at src/UniGetUI.Core.Tools/UpdaterDownloadEngine.cs:194
DeletePartialDownload(destinationPath, log);
return await DownloadInstallerPartAsync(
client,
identity,
destinationPath,
allowRestart: false,
log,
cancellationToken
);
}
response.EnsureSuccessStatusCode();
bool appendToPartial = response.StatusCode is HttpStatusCode.PartialContent;
if (appendToPartial && !IsValidPartialResponse(response, partialLength))
{
if (!allowRestart)
{
throw new InvalidDataException(
"The updater download server returned an invalid partial content range."
);
}
log?.Invoke("Updater download returned an invalid partial response; restarting.");
DeletePartialDownload(destinationPath, log);
return await DownloadInstallerPartAsync(
client,
identity,
destinationPath,
allowRestart: false,
log,
cancellationToken
);
}
if (appendToPartial && !IsResumeValidatorCompatible(metadata, response))
{View on GitHub (pinned to 9b1d7d0eab)
Solutions
- Delete the .part file and its .part.json metadata manually, then retry the download from scratch.
- Verify the download URL points to a server/CDN that correctly supports HTTP Range requests and returns accurate Content-Range headers.
- Check that the partial file was not externally modified between the initial download and the resume attempt.
- If behind a proxy, bypass it or reconfigure it to pass Range headers and Content-Range responses through unchanged.
Example fix
// before: partial file present but range mismatch keeps failing UpdaterDownloadEngine.DownloadInstallerPartAsync(client, identity, destPath) // after: clean residual partial state then retry UpdaterDownloadEngine.DeletePartialDownload(destPath); await UpdaterDownloadEngine.DownloadInstallerPartAsync(client, identity, destPath);
Defensive patterns
Strategy: retry
Validate before calling
if (File.Exists(UpdaterDownloadEngine.GetPartialPath(destPath)))
{
long partialLen = new FileInfo(UpdaterDownloadEngine.GetPartialPath(destPath)).Length;
if (partialLen == 0) UpdaterDownloadEngine.DeletePartialDownload(destPath);
} Try / catch
try { await UpdaterDownloadEngine.DownloadInstallerPartAsync(client, identity, destPath); }
catch (InvalidDataException ex) when (ex.Message.Contains("invalid partial content range"))
{ UpdaterDownloadEngine.DeletePartialDownload(destPath); /* retry fresh */ } Prevention
- Download from CDNs that correctly implement HTTP Range and Content-Range.
- Ensure no proxy rewrites Range responses.
- Clean up .part and .part.json files before starting a fresh download session.
When it happens
Trigger: A resume request (Range: bytes=N-) is sent. The server returns 206 but the Content-Range start byte differs from N. The engine deletes the partial, retries from byte 0 with allowRestart=false, and the server again returns 206 with a mismatched range start instead of a clean 200 or a correct 206. This requires a server that returns 206 status with inconsistent range data across two sequential requests.
Common situations: A reverse proxy or CDN rewrites Range responses incorrectly. The partial file was truncated externally and the metadata's recorded length drifted from the real file size. A load balancer routes the retry to a different backend that disagrees about the content range. The server does not support Range properly but advertises 206 anyway.
Related errors
- The updater download server returned partial content with a
- The completed updater partial file was not found.
- GitHub request failed with HTTP {(int)response.StatusCode} (
- No compatible installer file found in productinfo for archit
- GitHub returned an empty response.
AI-assisted analysis of Devolutions/UniGetUI@9b1d7d0eab (2026-08-13).
Data as JSON: /api/errors/c4f1ed949d77352c.
Report an issue: GitHub.