microsoft/FASTER · error · FasterException
Cannot commit in read-only mode
Error message
Cannot commit in read-only mode
What it means
FasterLog.CommitAsync (or Commit) was called on a FasterLog opened in read-only mode. A read-only log is typically attached for tailing/recovery on a replica and has no commit capability, so the library refuses the operation up front via this guard in FasterLog.cs:2704.
Solutions
- Check FasterLog.ReadOnlyMode (or how the instance was constructed) before calling any commit API and skip/branch the commit.
- Open the log in writable mode on the node that owns the log (do not pass read-only/recovery-only settings).
- On replicas, rely on log replication/checkpoint streaming from the primary instead of local commits.
- Wrap shared append helpers so commit calls are conditional on writability.
Example fix
// before
await log.CommitAsync();
// after
if (!log.ReadOnlyMode)
await log.CommitAsync(); Defensive patterns
Strategy: validation
Validate before calling
if (log.ReadOnlyMode) throw new InvalidOperationException("This node cannot commit; log is read-only"); Try / catch
try { await log.CommitAsync(); } catch (FasterException ex) when (ex.Message == "Cannot commit in read-only mode") { /* route write to primary */ } Prevention
- Check ReadOnlyMode before any write path runs
- Keep follower/replica code free of commit calls
- Centralize append+commit behind a writability check
When it happens
Trigger: Calling CommitAsync/Commit (including the fast-forward overload) on a FasterLog created with FastCommitMode or opened as a read-only subscriber/recover-only log where readOnlyMode is true.
Common situations: Opening a log on a backup node or with LogCommitManager pointing at an immutable snapshot, then reusing shared append code that unconditionally commits; connecting to a replicated log as a follower and calling the same enqueue-and-commit path as the primary.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Already recovered until address
- Cannot use named iterators with read-only FasterLog
- Cannot use scanUncommitted with read-only FasterLog
- This method can only be used with a read-only FasterLog…
- requested commit num is not available
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/04e5e354b2728e9f.
Report an issue: GitHub.
Appendix: source
Thrown at cs/src/core/FasterLog/FasterLog.cs:2704
length = GetLength(ptr);
// forego checksum verification since record may not be read in full by AsyncGetHeaderOnlyFromDiskCallback()
}
record.Return();
return length;
}
private bool CommitInternal(out long commitTail, out long actualCommitNum, bool fastForwardAllowed, byte[] cookie, long proposedCommitNum, Action callback)
{
if (cannedException != null)
throw cannedException;
commitTail = actualCommitNum = 0;
if (readOnlyMode)
throw new FasterException("Cannot commit in read-only mode");
if (fastForwardAllowed && (cookie != null || proposedCommitNum != -1 || callback != null))
throw new FasterException(
"Fast forwarding a commit is only allowed when no cookie, commit num, or callback is specified");
var info = new FasterLogRecoveryInfo
{
FastForwardAllowed = fastForwardAllowed,
Cookie = cookie,
Callback = callback,
};
info.SnapshotIterators(PersistedIterators);
var commitRequired = ShouldCommmitMetadata(ref info) || (commitCoveredAddress < TailAddress);
// Only apply commit policy if not a strong commit
if (fastForwardAllowed && !commitPolicy.AdmitCommit(TailAddress, commitRequired))
return false;
// This critical section serializes commit record creation / commit content generation and ensures that theView on GitHub (pinned to 321d872eab)