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
- Pass a normal, monotonically increasing commit number (or the default) instead of long.MaxValue.
- Stop producers before calling the commit that completes the log (commit with long.MaxValue is terminal).
- Add a guard/check before enqueue: if (commitNum == long.MaxValue) throw/return before touching the log.
- 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
- Never pass long.MaxValue as a commit number; treat it as a reserved sentinel.
- Complete the log only after all producers are shut down.
- Centralize commit-number generation in one monotonic source.
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
- Already recovered until address
- Cannot use named iterators with read-only FasterLog
- Cannot use scanUncommitted with read-only FasterLog
- Cannot use scanUncommitted without setting…
- Max length of iterator name is 20 characters
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)