microsoft/FASTER · error

AsyncFlushPagesToFile(), error: %u

Error message

AsyncFlushPagesToFile(), error: %u

What it means

This log_error fires inside the completion callback of PersistentMemoryMalloc::AsyncFlushPagesToFile, which asynchronously writes log pages out to a file. If the async write completes with a Status other than Status::Ok, the callback logs the status code; the pending-flush counter is then still decremented, so callers waiting on flush_pending will proceed even though the on-disk copy is incomplete or corrupt.

Solutions

  1. Map the logged status code to the actual file I/O failure and check the target file path, permissions, and free space
  2. Reopen or recreate the backing file at a valid, writable location and retry the flush
  3. Avoid disposing the device while flushes are pending; wait for flush_pending to reach zero before shutdown
  4. After a failed flush, do not trust the file copy — re-run the flush and validate the resulting file before deleting in-memory data
Defensive patterns

Strategy: try-catch

Validate before calling

// before dumping the log to file, ensure the target is writable
std::FILE* f = std::fopen(dump_path.c_str(), "ab");
bool writable = (f != nullptr);
if (f) std::fclose(f);

Try / catch

// flush_pending reaching zero does not mean success; poll/inspect logged failures
if (flush_failed.load()) { // set from your own tracking of 'AsyncFlushPagesToFile(), error' logs
  std::cerr << "Log dump incomplete; do not discard in-memory log\n";
  // recreate the dump file and retry the flush
}

Prevention

When it happens

Trigger: Calling AsyncFlushPagesToFile (used when persisting the log to a backing file, e.g. during dump-to-disk when memory is full or on truncation) and the underlying async file write fails: disk full, invalid/unwritable file path, device I/O error, or the device being disposed while writes are pending.

Common situations: Dumping the in-memory log to a file on a nearly full or failing disk; a file opened at an invalid path or without write permission; process shutdown racing with in-flight async writes.

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


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

Appendix: source

Thrown at cc/src/core/persistent_memory_malloc.h:939

    Context(std::atomic<uint32_t>& flush_pending_)
      : flush_pending{ flush_pending_ } {
    }
    /// The deep-copy constructor
    Context(Context& other)
      : flush_pending{ other.flush_pending } {
    }
   protected:
    Status DeepCopy_Internal(IAsyncContext*& context_copy) final {
      return IAsyncContext::DeepCopy_Internal(*this, context_copy);
    }
   public:
    std::atomic<uint32_t>& flush_pending;
  };

  auto callback = [](IAsyncContext* ctxt, Status result, size_t bytes_transferred) {
    CallbackContext<Context> context{ ctxt };
    if(result != Status::Ok) {
      log_error("AsyncFlushPagesToFile(), error: %u\n", static_cast<uint8_t>(result));
    }
    assert(context->flush_pending > 0);
    --context->flush_pending;
  };

  uint32_t num_pages = until_address.page() - start_page;
  if(until_address.offset() > 0) {
    ++num_pages;
  }
  assert(num_pages > 0);
  flush_pending = num_pages;

  for(uint32_t flush_page = start_page; flush_page < start_page + num_pages; ++flush_page) {
    Address page_start_address{ flush_page, 0 };
    Address page_end_address{ flush_page + 1, 0 };
    Context context{ flush_pending };
    RETURN_NOT_OK(file.WriteAsync(Page(flush_page), kPageSize * (flush_page - start_page),
                                  kPageSize, callback, context));

View on GitHub (pinned to 321d872eab)