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

  1. Deduplicate the USNJournalDataEntry collection by VolumeName per fileset before inserting.
  2. Serialize operations writing change-journal data for the same fileset.
  3. Run database repair to reconcile ChangeJournalData.
  4. 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

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


AI-assisted analysis of duplicati/duplicati@3f348be3e3 (2026-08-13). Data as JSON: /api/errors/63c7eaddf5c8f369. Report an issue: GitHub.