duplicati/duplicati · error · FileMissingException
FileMissing
FileMissing
Error message
The requested file does not exist
What it means
Thrown inside the private Info() method when the JFS GET for a single file returns HTTP 404 NotFound. Info() is called by ParallelGetAsync to learn the file size before chunking, so this surfaces during parallel downloads.
Source
Thrown at Duplicati/Library/Backend/Jottacloud/Jottacloud.cs:309
(var client, var _) = await GetClient(cancelToken).ConfigureAwait(false);
var doc = new System.Xml.XmlDocument();
try
{
// Send request and load XML response.
using var req = await CreateRequest(HttpMethod.Get, remotename, "", false, cancelToken).ConfigureAwait(false);
using var response = await Utility.Utility.WithTimeout(m_timeouts.ListTimeout, cancelToken,
innerCancellationToken =>
client.GetResponseAsync(req, HttpCompletionOption.ResponseHeadersRead, innerCancellationToken))
.ConfigureAwait(false);
await using var rs = await response.Content.ReadAsStreamAsync(cancelToken).ConfigureAwait(false);
doc.Load(rs);
}
catch (HttpRequestException wex)
{
if (wex.StatusCode == HttpStatusCode.NotFound)
throw new FileMissingException(wex);
throw;
}
// Handle XML response. Since we in the constructor demand a folder below the mount point we know the root
// element must be a "folder", else it could also have been a "mountPoint" (which has a very similar structure).
// We must check for "deleted" attribute, because files/folders which has it is deleted (attribute contains the timestamp of deletion)
// so we treat them as non-existent here.
var xFile = doc.DocumentElement;
if (xFile?.Attributes["deleted"] != null)
throw new FileMissingException($"{LC.L("The requested file does not exist")}: {remotename}");
return ToFileEntry(xFile);
}
/// <inheritdoc/>
public async Task PutAsync(string remotename, string filename, CancellationToken cancelToken)
{
await using var fs = File.OpenRead(filename);View on GitHub (pinned to 3f348be3e3)
Solutions
- Verify the file appears in ListAsync output before downloading.
- If a concurrent operation deletes files, serialize or re-list before each get.
- Treat as transient and retry once the expected file is present.
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the file is listed before parallel download
var exists = false;
await foreach (var e in backend.ListAsync(token))
if (e.Name == remotename) { exists = true; break; }
if (!exists) throw new FileNotFoundException(remotename); Try / catch
try { await backend.GetAsync(remotename, dest, token); }
catch (FileMissingException ex) { logger.LogWarning("File gone: {Message}", ex.Message); /* skip or re-list */ } Prevention
- Re-list before downloading if a concurrent purge may remove block files.
- Serialize delete and get operations on the same backend to avoid races.
- Validate remote names against the latest list before issuing parallel gets.
When it happens
Trigger: Requesting Info (via GetAsync with m_threads > 1) for a remotename that does not exist on the server, or that was deleted between the list call and the get call.
Common situations: A backup block file was already deleted by a concurrent purge; the remote name is misspelled; another client removed the file; an interrupted prior run left the remote state inconsistent.
Related errors
- FolderMissing
- FileMissing
- The requested file does not exist: {remotename}
- {remotename}
- Invalid Content-Range response for chunk {chunk.start}-{chun
AI-assisted analysis of duplicati/duplicati@3f348be3e3 (2026-08-13).
Data as JSON: /api/errors/0fc002c7b6919d4d.
Report an issue: GitHub.