microsoft/FASTER · error · FasterException

Attempting to enqueue into a completed log

Error message

Attempting to enqueue into a completed log

What it means

Enqueue(self, entry, commitNum, ...) rejects entries whose commitNum equals long.MaxValue, the sentinel value the log uses to mark a completed (sealed) log tail. Once the log has been completed via Commit(long.MaxValue)-style APIs, no further enqueues are permitted. The check runs after epoch.Resume() so the exception is thrown directly to the caller.

Solutions

  1. Pass a normal, monotonically increasing commit number (or the default) instead of long.MaxValue.
  2. Stop producers before calling the commit that completes the log (commit with long.MaxValue is terminal).
  3. Add a guard/check before enqueue: if (commitNum == long.MaxValue) throw/return before touching the log.
  4. Route post-completion writes to a new log instance/device.

Example fix

// before
log.Enqueue(data, long.MaxValue); // sentinel means 'completed log'
// after
log.Enqueue(data, ++commitNumber);
Defensive patterns

Strategy: validation

Validate before calling

if (commitNum == long.MaxValue)
    throw new InvalidOperationException("long.MaxValue marks a completed log; use a real commit number");

Type guard

static bool IsValidCommitNumber(long commitNum) => commitNum != long.MaxValue;

Try / catch

try { log.Enqueue(data, commitNum); }
catch (FasterException ex) when (ex.Message == "Attempting to enqueue into a completed log")
{
    // log is sealed: redirect writes or stop producer
}

Prevention

When it happens

Trigger: Calling FasterLog.Enqueue(IBatchEntry/byte[] entry, long commitNum) passing commitNum == long.MaxValue, on a log that has been marked completed.

Common situations: Hard-coding or mis-deriving a commit number that collides with the long.MaxValue 'completed' sentinel; a producer that started before Commit(long.MaxValue) and keeps enqueueing afterward; copying example code that used long.MaxValue as an 'unspecified' marker.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15). Data as JSON: /api/errors/fec6efb01518d0c3. Report an issue: GitHub.

Appendix: source

Thrown at cs/src/core/FasterLog/FasterLog.cs:500

        #region TryEnqueue
        /// <summary>
        /// Try to enqueue entry to log (in memory). If it returns true, we are
        /// done. If it returns false, we need to retry.
        /// </summary>
        /// <param name="entry">Entry to be enqueued to log</param>
        /// <param name="logicalAddress">Logical address of added entry</param>
        /// <typeparam name="T">type of entry</typeparam>
        /// <returns>Whether the append succeeded</returns>
        public unsafe bool TryEnqueue<T>(T entry, out long logicalAddress) where T : ILogEnqueueEntry
        {
            logicalAddress = 0;
            var length = entry.SerializedLength;
            int allocatedLength = headerSize + Align(length);
            ValidateAllocatedLength(allocatedLength);

            epoch.Resume();

            if (commitNum == long.MaxValue) throw new FasterException("Attempting to enqueue into a completed log");

            logicalAddress = allocator.TryAllocateRetryNow(allocatedLength);
            if (logicalAddress == 0)
                if (logicalAddress == 0)
                {
                    epoch.Suspend();
                    if (cannedException != null) throw cannedException;
                    return false;
                }

            var physicalAddress = allocator.GetPhysicalAddress(logicalAddress);
            entry.SerializeTo(new Span<byte>((void*)(headerSize + physicalAddress), length));
            SetHeader(length, (byte*)physicalAddress);
            if (AutoRefreshSafeTailAddress) DoAutoRefreshSafeTailAddress();
            epoch.Suspend();
            if (AutoCommit) Commit();
            return true;
        }

View on GitHub (pinned to 321d872eab)