dotnet/machinelearning · error · IOException
Model file still got locked after 5 seconds, fail to reload.
Error message
Model file {_filePath} still got locked after 5 seconds, fail to reload. What it means
FileModelLoader.LoadModel opens the model file with a 5-second retry loop via WaitForFile; if the file remains locked by another process after 5 seconds it returns null and this IOException is thrown so the reload aborts instead of loading a partial or unreadable model. The ML.NET context never receives a stream, so _model keeps its previous value.
Solutions
- Ensure the producer writes the model atomically: write to a temp file and File.Move/replace onto the watched path so readers never see a locked file
- Close the application or process holding an exclusive handle on the model file before triggering reload
- Increase tolerance by retrying the load in your own code (catch IOException and call LoadModel again after a delay)
- Exclude the model directory from antivirus real-time scanning
Example fix
// before: producer overwrites watched file directly mlContext.Model.Save(model, schema, File.Create(modelPath)); // after: atomic replace var tmp = modelPath + ".tmp"; using (var fs = File.Create(tmp)) mlContext.Model.Save(model, schema, fs); File.Move(tmp, modelPath, overwrite: true);
Defensive patterns
Strategy: retry
Validate before calling
// before triggering reload
var fi = new FileInfo(modelPath);
using (var probe = fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) { } // throws IOException while locked Type guard
bool IsFileReadable(string path) { try { using var _ = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); return true; } catch (IOException) { return false; } } Try / catch
try { loader.Start(); } catch (IOException ex) when (ex.Message.Contains("still got locked")) { await Task.Delay(TimeSpan.FromSeconds(5)); retryLoad(); } Prevention
- Write model files atomically (temp file + rename)
- Never keep handles open on files the watcher monitors
- Exclude model dirs from AV/backup locking
When it happens
Trigger: Calling Start() or a file watcher change (WatcherChanged) triggering LoadModel() while the .zip model file is held open with an exclusive lock (FileShare incompatible with Read) for over 5 seconds.
Common situations: Another process (e.g. a trainer, backup/AV scanner, or an mlnet CLI training job) is still writing or holding the model file when the app hot-swaps it; copying the model over the same path without atomic rename; antivirus holding the file briefly after write.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- Cannot read the file Merge file.
- Cannot read the file Merge file.
- Directory " " does not exist.
- File too big to open.
- Stream should be non-null and its stream.CanRead property…
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/9899fad930919e61.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.Extensions.ML/ModelLoaders/FileModelLoader.cs:136
catch (IOException)
{
if (fs != null)
{
fs.Dispose();
}
Thread.Sleep(50);
}
}
return null;
}
//internal virtual for testing purposes.
internal virtual void LoadModel()
{
var fs = WaitForFile(_filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
if (fs == null)
throw new IOException($"Model file {_filePath} still got locked after 5 seconds, fail to reload.");
using (fs)
{
_model = _context.Model.Load(fs, out _);
}
}
public void Dispose()
{
_watcher?.Dispose();
}
internal static class EventIds
{
public static readonly EventId FileReloadBegin = new EventId(100, "FileReloadBegin");
public static readonly EventId FileReloadEnd = new EventId(101, "FileReloadEnd");
public static readonly EventId FileReload = new EventId(102, "FileReload");
public static readonly EventId FileReloadError = new EventId(103, nameof(FileReloadError));View on GitHub (pinned to 7b76e69cf9)