duplicati/duplicati · error · Exception
Failed to parse response
Error message
Failed to parse response
What it means
Thrown in PutAsync (B2.cs:370) after a successful file upload. The HTTP status was 2xx (EnsureSuccessStatusCode passed), but deserializing the response body as UploadFileResponse using Newtonsoft.Json returned null. This means the body was empty, contained literal JSON null, or did not match any properties of UploadFileResponse.
Source
Thrown at Duplicati/Library/Backend/Backblaze/B2.cs:370
request.Headers.TryAddWithoutValidation("Authorization", uploadUrlData.AuthorizationToken);
request.Headers.Add("X-Bz-Content-Sha1", sha1);
request.Headers.Add("X-Bz-File-Name", _urlencodedPrefix + Utility.UrlEncoding.UrlPathEncode(remotename));
request.Content = new StreamContent(timeoutStream);
request.Content.Headers.Add("Content-Type", "application/octet-stream");
request.Content.Headers.Add("Content-Length", timeoutStream.Length.ToString());
var response = await _httpClient.UploadStream(request, cancelToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var rdata = await response.Content.ReadAsStreamAsync(cancelToken).ConfigureAwait(false);
UploadFileResponse fileinfo;
using (var tr = new StreamReader(rdata))
await using (var jr = new Newtonsoft.Json.JsonTextReader(tr))
fileinfo = new Newtonsoft.Json.JsonSerializer().Deserialize<UploadFileResponse>(jr)
?? throw new Exception("Failed to parse response");
// Delete old versions
if (_filecache!.ContainsKey(remotename))
await DeleteAsync(remotename, cancelToken).ConfigureAwait(false);
_filecache[remotename] =
[
new FileEntity
{
FileID = fileinfo.FileID,
FileName = fileinfo.FileName,
Action = "upload",
Size = fileinfo.ContentLength,
UploadTimestamp = (long)(DateTime.UtcNow - Utility.Utility.EPOCH).TotalMilliseconds
}
];
}
catch (Exception ex)View on GitHub (pinned to 3f348be3e3)
Solutions
- Retry the upload to rule out transient response corruption or B2 maintenance
- Inspect network path for proxies or appliances intercepting upload traffic to the B2 upload URL
- Update Duplicati to the latest version in case of B2 API response schema changes
Defensive patterns
Strategy: retry
Try / catch
var maxRetries = 3;
for (int attempt = 0; attempt < maxRetries; attempt++)
{
try { await backend.PutAsync(remotename, stream, cancelToken); break; }
catch (Exception ex) when (ex.Message == "Failed to parse response" && attempt < maxRetries - 1)
{
// Upload HTTP succeeded but response was unparseable; retry the upload
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)), cancelToken);
}
} Prevention
- Wrap PutAsync calls in a retry loop since upload response parsing failures can be transient
- Log the raw HTTP response body when this error occurs to diagnose proxy or encoding issues
- Verify no intermediary modifies upload responses from B2
When it happens
Trigger: PutAsync completes the HTTP upload to the B2 upload URL. response.Content.ReadAsStreamAsync provides the body. A StreamReader + Newtonsoft.Json.JsonTextReader feeds into JsonSerializer.Deserialize<UploadFileResponse>. If the result is null, the upload response could not be parsed.
Common situations: Network intermediary (proxy, CDN, firewall) truncating or replacing the upload response; B2 API returning an unexpected response format during maintenance; response encoding issue (e.g. double-gzip); Duplicati version incompatible with a B2 API schema change.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- BucketID is null
- Failed to parse authorization response
- Failed to deserialize upload response
- Missing file ID
- Failed to set object lock, call succeeded but no retention i
AI-assisted analysis of duplicati/duplicati@3f348be3e3 (2026-08-13).
Data as JSON: /api/errors/8f832b865026ee64.
Report an issue: GitHub.