microsoft/FASTER · error
AsyncFlushPages(), error: %u
Error message
AsyncFlushPages(), error: %u
What it means
This log_error fires inside the async flush-pages completion callback of PersistentMemoryMalloc::AsyncFlushPages. When the asynchronous file write of a log page completes with a Status other than Status::Ok, the callback logs the raw status code instead of throwing — the page's LastFlushedUntilAddress is still advanced. It indicates the underlying async disk flush of a FASTER log page failed (or was folded with a failure), which can leave durability guarantees broken.
Solutions
- Inspect the logged status code (a FASTER Status enum value cast to uint8_t) and map it to the underlying device/file error
- Check free disk space and the health of the checkpoint/log directory
- Ensure the store (and its device) is not shut down or checkpointed concurrently in a way that outlives the device's lifetime; wait for checkpoints to complete before Close
- Retry the checkpoint/flush after fixing the storage problem; verify durability with a checkpoint that completes with Status::Ok
Defensive patterns
Strategy: try-catch
Validate before calling
// before checkpointing/flushing
struct statvfs st;
if (statvfs(checkpoint_dir.c_str(), &st) != 0 || st.f_bavail * st.f_frsize < required_bytes) {
// abort checkpoint: not enough space for the flush
} Try / catch
if (!store->Checkpoint(token, callback, ctx).IsPending() && /* completed with */ status != Status::Ok) {
// async flush failures are logged, not thrown; check the returned/adjunct status
std::cerr << "Checkpoint flush failed; durability not guaranteed\n";
// retry after checking disk space / device health
} Prevention
- Monitor free disk space on the checkpoint volume before initiating checkpoints
- Never shut down or dispose the FASTER device while async flushes are pending — wait for checkpoint completion callbacks
- Treat non-Ok statuses logged as 'AsyncFlushPages(), error' as a durability warning and re-checkpoint
- Keep checkpoint directories on healthy, writable local storage (avoid flaky network mounts)
When it happens
Trigger: AsyncFlushPages / Flush (and hence safe checkpoints or log truncation) issues async writes via the device's async file IO; the completion returns a failed Status — e.g. disk full, I/O error, device closed/shutdown racing with pending writes, or failed file writes on Windows/Linux async IO paths.
Common situations: Disk out of space during checkpoint flush; storage device failures; shutting down a FASTER store while flushes are still in flight; misconfigured checkpoint directory (unmounted volume, permissions) so async writes fail.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- AsyncFlushPagesToFile(), error: %u
- Unable to set first valid segment to
- Unable to set last valid segment to
- Can spin-wait for commit (checkpoint completion) only if…
- Make sure all async operations issued on this session are…
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/130655c8b49ba758.
Report an issue: GitHub.
Appendix: source
Thrown at cc/src/core/persistent_memory_malloc.h:869
Context(const Context& other)
: allocator{ other.allocator }
, page{ other.page }
, until_address{ other.until_address } {
}
protected:
Status DeepCopy_Internal(IAsyncContext*& context_copy) final {
return IAsyncContext::DeepCopy_Internal(*this, context_copy);
}
public:
alloc_t* allocator;
uint32_t page;
Address until_address;
};
auto callback = [](IAsyncContext* ctxt, Status result, size_t bytes_transferred) {
CallbackContext<Context> context{ ctxt };
if(result != Status::Ok) {
log_error("AsyncFlushPages(), error: %u\n", static_cast<uint8_t>(result));
}
context->allocator->PageStatus(context->page).LastFlushedUntilAddress.store(
context->until_address);
//Set the page status to flushed
FlushCloseStatus old_status = context->allocator->PageStatus(context->page).status.load();
FlushCloseStatus new_status;
do {
new_status = FlushCloseStatus{ FlushStatus::Flushed, old_status.close };
} while(!context->allocator->PageStatus(context->page).status.compare_exchange_weak(
old_status, new_status));
if(old_status.close == CloseStatus::Closed) {
// We finished flushing the page after it was closed, so we are responsible for clearing and
// reopening it.
std::memset(context->allocator->Page(context->page), 0, kPageSize);
context->allocator->PageStatus(context->page).status.store(FlushStatus::Flushed,
CloseStatus::Open);
}
context->allocator->ShiftFlushedUntilAddress();View on GitHub (pinned to 321d872eab)