duplicati/duplicati · error · Exception
Unable to add change journal entry
Error message
Unable to add change journal entry
What it means
Generic Exception in CreateChangeJournalDataAsync: the INSERT into ChangeJournalData (NTFS USN change-journal data per fileset/volume) returned != 1 affected row for an entry. Each iteration inserts one row, so a count other than 1 signals a constraint violation, a race, or a schema issue with that journal entry.
Source
Thrown at Duplicati/Library/Main/Database/Local/LocalBackupDatabase.cs:1975
)
VALUES (
@FilesetId,
@VolumeName,
@JournalId,
@NextUsn,
@ConfigHash
);
")
.SetParameterValue("@FilesetId", m_filesetId)
.SetParameterValue("@VolumeName", entry.Volume)
.SetParameterValue("@JournalId", entry.JournalId)
.SetParameterValue("@NextUsn", entry.NextUsn)
.SetParameterValue("@ConfigHash", entry.ConfigHash)
.ExecuteNonQueryAsync(token) // Not logging, as we log the whole operation
.ConfigureAwait(false);
if (c != 1)
throw new Exception("Unable to add change journal entry");
}
await m_rtr.CommitAsync(token: token).ConfigureAwait(false);
}
/// <summary>
/// Adds NTFS change journal data for file set and volume.
/// </summary>
/// <param name="data">Data to add.</param>
/// <param name="fileSetId">Existing file set to update.</param>
/// <param name="token">The cancellation token to cancel the operation.</param>
/// <returns>A task that completes when the data is added.</returns>
public async Task UpdateChangeJournalDataAsync(IEnumerable<Interface.USNJournalDataEntry> data, long fileSetId, CancellationToken token)
{
using (new Logging.Timer(LOGTAG, "UpdateChangeJournalData", "Updating USN entries"))
foreach (var entry in data)
{
await using var cmd = m_connection.CreateCommand();View on GitHub (pinned to 3f348be3e3)
Solutions
- Deduplicate the USNJournalDataEntry collection by VolumeName per fileset before inserting.
- Serialize operations writing change-journal data for the same fileset.
- Run database repair to reconcile ChangeJournalData.
- If a duplicate entry is benign for your workflow, filter it out upstream.
Defensive patterns
Strategy: validation
Validate before calling
// Deduplicate entries by VolumeName before calling CreateChangeJournalDataAsync: var distinct = data.GroupBy(e => e.Volume).Select(g => g.First()); await db.CreateChangeJournalDataAsync(distinct, token);
Try / catch
try { await db.CreateChangeJournalDataAsync(data, token); }
catch (Exception ex) when (ex.Message.Contains("Unable to add change journal entry"))
{ Log.Error("ChangeJournal insert conflict; deduplicate per-volume and serialize writers."); throw; } Prevention
- Provide at most one USN entry per (FilesetID, VolumeName).
- Serialize backup operations that write NTFS change-journal data.
When it happens
Trigger: Call CreateChangeJournalDataAsync(data) where one entry's INSERT into ChangeJournalData returns 0 or >1 rows (e.g. a UNIQUE(FilesetID,VolumeName) constraint blocks it, or a concurrent insert already added the row).
Common situations: Duplicate volume entries in the same fileset; UNIQUE constraint on (FilesetID, VolumeName) already satisfied; concurrent backup writing the same journal data; schema/migration change; interrupted prior write.
Related errors
- Hash is null
- Failed to move block {key} with size {size}, result count: {
- Failed to insert block {key} with size {size}, result count:
- Failed to insert blocklist hash {bh} for blockset {blockseti
- Could not find any blocks with the given hash: {h}
AI-assisted analysis of duplicati/duplicati@3f348be3e3 (2026-08-13).
Data as JSON: /api/errors/63c7eaddf5c8f369.
Report an issue: GitHub.