microsoft/FASTER · error · FasterException
Cannot use LocalStorageDevice from non-Windows OS platform…
Error message
Cannot use LocalStorageDevice from non-Windows OS platform, use ManagedLocalStorageDevice instead.
What it means
LocalStorageDevice uses Windows-native APIs (IO completion ports, Native32 Win32 calls) and therefore only works on Windows. On Linux/macOS the constructor immediately throws, directing developers to ManagedLocalStorageDevice, which uses the cross-platform .NET file API.
Solutions
- Use Devices.CreateLogDevice(...), which on .NET (Core) selects ManagedLocalStorageDevice on non-Windows platforms.
- Explicitly instantiate ManagedLocalStorageDevice for cross-platform local storage.
- Guard device creation with RuntimeInformation checks if you must construct devices manually per OS.
Example fix
// before
var device = new LocalStorageDevice("/data/store.log");
// after
var device = new ManagedLocalStorageDevice("/data/store.log"); Defensive patterns
Strategy: validation
Validate before calling
var device = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? new LocalStorageDevice(path)
: new ManagedLocalStorageDevice(path); Type guard
static bool IsWindows() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
Prevention
- Prefer Devices.CreateLogDevice factory over constructing device classes directly.
- Test deployments on the target OS (Linux containers) in CI.
- Use ManagedLocalStorageDevice by default for cross-platform builds.
When it happens
Trigger: Calling new LocalStorageDevice(...) (or Devices.CreateLogDevice choosing it) on a non-Windows OS, detected via RuntimeInformation.IsOSPlatform(OSPlatform.Windows) == false.
Common situations: Deploying a Windows-developed FASTER application to Linux containers/Kubernetes without changing the device factory; CI running on Linux agents.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- Allocator with sector size
- Getting handle in disposed device
- Local memory device must have a capacity!
- Out of order message within session
- Unexpected status of SubscribeKV
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/9a626896a9b1983f.
Report an issue: GitHub.
Appendix: source
Thrown at cs/src/core/Device/LocalStorageDevice.cs:107
/// <param name="deleteOnClose"></param>
/// <param name="disableFileBuffering"></param>
/// <param name="capacity">The maximum number of bytes this storage device can accommondate, or CAPACITY_UNSPECIFIED if there is no such limit </param>
/// <param name="recoverDevice">Whether to recover device metadata from existing files</param>
/// <param name="initialLogFileHandles">Optional set of preloaded safe file handles, which can speed up hydration of preexisting log file handles</param>
/// <param name="useIoCompletionPort">Whether we use IO completion port with polling</param>
protected internal LocalStorageDevice(string filename,
bool preallocateFile = false,
bool deleteOnClose = false,
bool disableFileBuffering = true,
long capacity = Devices.CAPACITY_UNSPECIFIED,
bool recoverDevice = false,
IEnumerable<KeyValuePair<int, SafeFileHandle>> initialLogFileHandles = null,
bool useIoCompletionPort = true)
: base(filename, GetSectorSize(filename), capacity)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
throw new FasterException("Cannot use LocalStorageDevice from non-Windows OS platform, use ManagedLocalStorageDevice instead.");
}
if (filename.Length > Native32.WIN32_MAX_PATH - 11) // -11 to allow for ".<segment>"
throw new FasterException($"Path {filename} is too long");
ThrottleLimit = 120;
this.useIoCompletionPort = useIoCompletionPort;
this._disposed = false;
if (useIoCompletionPort)
{
ThreadPool.GetMaxThreads(out int workerThreads, out _);
ioCompletionPort = Native32.CreateIoCompletionPort(new SafeFileHandle(new IntPtr(-1), false), IntPtr.Zero, UIntPtr.Zero, (uint)(workerThreads + NumCompletionThreads));
for (int i = 0; i < NumCompletionThreads; i++)
{
var thread = new Thread(() => new LocalStorageDeviceCompletionWorker().Start(ioCompletionPort, _callback))
{
IsBackground = trueView on GitHub (pinned to 321d872eab)