microsoft/FASTER · error · FasterException
This method can only be used with a read-only FasterLog…
Error message
This method can only be used with a read-only FasterLog instance used for iteration. Set FasterLogSettings.ReadOnlyMode to true during creation to indicate this.
What it means
RecoverReadOnly() synchronously advances a log instance to the latest valid commit, but this is only meaningful for instances created in read-only mode. FasterLog checks readOnlyMode at FasterLog.cs:2209 and throws if the instance is a normal (writable) log.
Solutions
- Set FasterLogSettings.ReadOnlyMode = true when constructing the instance used for iteration.
- Use a separate read-only FasterLog instance for recovery/iteration instead of the writable producer instance.
- On a writable log, recovery happens automatically at construction or via commit APIs; remove the RecoverReadOnly call.
Example fix
// before
var log = new FasterLog(new FasterLogSettings { LogDevice = sharedDevice });
log.RecoverReadOnly();
// after
var log = new FasterLog(new FasterLogSettings { LogDevice = sharedDevice, ReadOnlyMode = true });
log.RecoverReadOnly(); Defensive patterns
Strategy: validation
Validate before calling
// caller-side guard
if (!logSettings.ReadOnlyMode)
throw new InvalidOperationException("RecoverReadOnly requires FasterLogSettings.ReadOnlyMode = true"); Try / catch
try { log.RecoverReadOnly(); } catch (FasterException ex) when (ex.Message.Contains("read-only FasterLog instance")) { /* use a read-only instance */ } Prevention
- Keep producer and consumer FasterLog instances separate with clearly named factories.
- Only call RecoverReadOnly on instances obtained from a CreateReadOnly factory.
- Document replication settings in one place to avoid dropping ReadOnlyMode.
When it happens
Trigger: Calling FasterLog.RecoverReadOnly() on an instance created without FasterLogSettings.ReadOnlyMode = true.
Common situations: Developers replicating the read-only replication pattern (a follower tailing a shared log device) forget to set ReadOnlyMode in settings, then call RecoverReadOnly in their polling loop; often after copying code from the read-only FasterLog sample.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unexpected entry type
- Unable to set first valid segment to
- Unable to set last valid segment to
- Session named already exists in recovery info, use…
- Unable to find session named
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/1b3e9b07e87cd716.
Report an issue: GitHub.
Appendix: source
Thrown at cs/src/core/FasterLog/FasterLog.cs:2209
foreach (var item in _lastPersistedIterators)
{
if (info.Iterators.TryGetValue(item.Key, out var other))
{
if (item.Value != other) return true;
}
else
return true;
}
return false;
}
/// <summary>
/// Synchronously recover instance to FasterLog's latest valid commit, when being used as a readonly log iterator
/// </summary>
public void RecoverReadOnly()
{
if (!readOnlyMode)
throw new FasterException("This method can only be used with a read-only FasterLog instance used for iteration. Set FasterLogSettings.ReadOnlyMode to true during creation to indicate this.");
RestoreLatest(out _, out _);
SignalWaitingROIterators();
}
/// <summary>
/// Asynchronously recover instance to FasterLog's latest commit, when being used as a readonly log iterator
/// </summary>
public async ValueTask RecoverReadOnlyAsync(CancellationToken cancellationToken = default)
{
if (!readOnlyMode)
throw new FasterException("This method can only be used with a read-only FasterLog instance used for iteration. Set FasterLogSettings.ReadOnlyMode to true during creation to indicate this.");
await RestoreLatestAsync(cancellationToken).ConfigureAwait(false);
SignalWaitingROIterators();
}
private void SignalWaitingROIterators()View on GitHub (pinned to 321d872eab)