microsoft/FASTER · error · FasterException

Cannot use scanUncommitted without setting…

Error message

Cannot use scanUncommitted without setting AutoRefreshSafeTailAddress to true in FasterLog settings

What it means

FasterLog's Scan (iterator) API rejects scanUncommitted=true when the log was not created with AutoRefreshSafeTailAddress=true. Scanning uncommitted entries requires the log's safe tail address to be continuously refreshed, which only happens when that setting is enabled. The library throws eagerly at iterator creation in FasterLog.cs:1824 rather than producing subtly stale iteration results.

Solutions

  1. Set FasterLogSettings.AutoRefreshSafeTailAddress = true when creating the FasterLog instance, then reopen it.
  2. If uncommitted scanning is not required, pass scanUncommitted: false to Scan.
  3. If using a read-only log instance for tailing, verify the settings used to construct it enable AutoRefreshSafeTailAddress.

Example fix

// before
var log = new FasterLog(new FasterLogSettings { LogDevice = device });
var iter = log.Scan(0, long.MaxValue, scanUncommitted: true);
// after
var log = new FasterLog(new FasterLogSettings { LogDevice = device, AutoRefreshSafeTailAddress = true });
var iter = log.Scan(0, long.MaxValue, scanUncommitted: true);
Defensive patterns

Strategy: validation

Validate before calling

// before creating a tailing iterator
if (scanUncommitted && !logSettings.AutoRefreshSafeTailAddress)
    throw new InvalidOperationException("scanUncommitted requires FasterLogSettings.AutoRefreshSafeTailAddress = true");

Try / catch

try { var iter = log.Scan(0, long.MaxValue, scanUncommitted: true); } catch (FasterException ex) when (ex.Message.Contains("AutoRefreshSafeTailAddress")) { /* fix settings or use scanUncommitted:false */ }

Prevention

When it happens

Trigger: Calling FasterLog.Scan/Scan(beginAddress, endAddress, name, scanUncommitted: true, ...) on a log whose FasterLogSettings.AutoRefreshSafeTailAddress was not set to true.

Common situations: Developers building tailing/follow-the-tail iterators over the log enable scanUncommitted but forget the companion setting in the FasterLogSettings used at construction; also common when copying iterator code from samples that used a read-only log configured differently.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

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

        /// <param name="recover">Whether to recover named iterator from latest commit (if exists). If false, iterator starts from beginAddress.</param>
        /// <param name="scanBufferingMode">Use single or double buffering</param>
        /// <param name="scanUncommitted">Whether we scan uncommitted data</param>
        /// <param name="logger"></param>
        /// <returns></returns>
        public FasterLogScanIterator Scan(long beginAddress, long endAddress, string name = null, bool recover = true, ScanBufferingMode scanBufferingMode = ScanBufferingMode.DoublePageBuffering, bool scanUncommitted = false, ILogger logger = null)
        {
            if (readOnlyMode)
            {
                scanBufferingMode = ScanBufferingMode.SinglePageBuffering;

                if (name != null)
                    throw new FasterException("Cannot use named iterators with read-only FasterLog");
                if (scanUncommitted)
                    throw new FasterException("Cannot use scanUncommitted with read-only FasterLog");
            }

            if (scanUncommitted && !AutoRefreshSafeTailAddress)
                throw new FasterException("Cannot use scanUncommitted without setting AutoRefreshSafeTailAddress to true in FasterLog settings");

            FasterLogScanIterator iter;
            if (recover && name != null && RecoveredIterators != null && RecoveredIterators.ContainsKey(name))
                iter = new FasterLogScanIterator(this, allocator, RecoveredIterators[name], endAddress, getMemory, scanBufferingMode, epoch, headerSize, name, scanUncommitted, logger: logger);
            else
                iter = new FasterLogScanIterator(this, allocator, beginAddress, endAddress, getMemory, scanBufferingMode, epoch, headerSize, name, scanUncommitted, logger: logger);

            if (name != null)
            {
                if (name.Length > 20)
                    throw new FasterException("Max length of iterator name is 20 characters");
                if (PersistedIterators.ContainsKey(name))
                    logger?.LogDebug("Iterator name exists, overwriting");
                PersistedIterators[name] = iter;
            }

            if (Interlocked.Increment(ref logRefCount) == 1)
                throw new FasterException("Cannot scan disposed log instance");

View on GitHub (pinned to 321d872eab)