microsoft/FASTER · error · FasterException
Max length of iterator name is 20 characters
Error message
Max length of iterator name is 20 characters
What it means
Named (persisted) iterator names are limited to 20 characters because the name is stored inline in persisted iterator metadata. FasterLog.ValidateName checks this after creating the scan iterator in FasterLog.cs:1835 and throws FasterException when exceeded.
Solutions
- Shorten the iterator name to 20 characters or fewer (e.g. a hash or truncated prefix).
- Use a short name and map it to a longer logical description in your own configuration.
- If you need unique long identifiers, store a 20-char key (e.g. base64/hash of the full name) in PersistedIterators.
Example fix
// before var iter = log.Scan(0, long.MaxValue, name: "order-events-consumer-group-1", recover: true); // after var iter = log.Scan(0, long.MaxValue, name: "orders-cg-1", recover: true);
Defensive patterns
Strategy: validation
Validate before calling
if (iteratorName?.Length > 20)
throw new ArgumentException("FasterLog iterator name must be <= 20 characters", nameof(iteratorName)); Try / catch
try { var iter = log.Scan(0, long.MaxValue, name: name, recover: true); } catch (FasterException ex) when (ex.Message.Contains("Max length of iterator name")) { /* shorten name and retry */ } Prevention
- Generate persisted iterator names from short hashes (e.g. 16-char hex) instead of descriptive strings.
- Validate names at configuration load time, before constructing the log.
- Define a name factory that enforces the 20-char limit.
When it happens
Trigger: Calling FasterLog.Scan(..., name: "a-name-longer-than-20-characters", recover: true) with a name whose Length > 20.
Common situations: Developers use descriptive iterator names like "subscription-processor-west" or GUID strings (36 chars) for durable iterators that must survive restarts, exceeding the fixed 20-char limit.
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
- Cannot use scanUncommitted without setting…
- Cannot use named iterators with read-only FasterLog
- Cannot use scanUncommitted with read-only FasterLog
- Cannot scan disposed log instance
- This method can only be used with a read-only FasterLog…
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/e6c777e5a7e8b7a9.
Report an issue: GitHub.
Appendix: source
Thrown at cs/src/core/FasterLog/FasterLog.cs:1835
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");
return iter;
}
/// <summary>
/// Random read record from log, at given address
/// </summary>
/// <param name="address">Logical address to read from</param>
/// <param name="estimatedLength">Estimated length of entry, if known</param>
/// <param name="token">Cancellation token</param>
/// <returns></returns>
public async ValueTask<(byte[], int)> ReadAsync(long address, int estimatedLength = 0, CancellationToken token = default)View on GitHub (pinned to 321d872eab)