stride3d/stride · error · UnauthorizedAccessException
ZIP archive are read-only.
Error message
ZIP archive are read-only.
What it means
ZipFileSystemProvider supports only read access: OpenStream throws UnauthorizedAccessException when mode is not VirtualFileMode.Open or access is not VirtualFileAccess.Read, because ZIP archives loaded by this provider cannot be written.
Solutions
- Use VirtualFileMode.Open with VirtualFileAccess.Read when reading from ZIP providers.
- Redirect write operations to a writable FileSystemProvider mount instead of the ZIP.
- Guard writes: check the provider type (is ZipFileSystemProvider) and route to a writable provider.
- Use WriteAllData-style helpers only on writable mounts.
Example fix
// before var s = zipProvider.OpenStream(url, VirtualFileMode.Create, VirtualFileAccess.Write); // after var s = zipProvider.OpenStream(url, VirtualFileMode.Open, VirtualFileAccess.Read); // ZIPs are read-only // write elsewhere: // writableProvider.OpenStream(url, VirtualFileMode.Create, VirtualFileAccess.Write);
Defensive patterns
Strategy: type-guard
Validate before calling
bool isReadOnly = provider is ZipFileSystemProvider;
if (isReadOnly && (mode != VirtualFileMode.Open || access != VirtualFileAccess.Read))
throw new InvalidOperationException("ZIP providers are read-only; use a writable mount."); Type guard
bool IsZipProvider(IVirtualFileProvider p) => p is ZipFileSystemProvider;
Try / catch
try { stream = provider.OpenStream(url, mode, access); }
catch (UnauthorizedAccessException) { stream = fallbackWritableProvider.OpenStream(url, mode, access); } Prevention
- Route all writes to FileSystemProvider-backed mounts, never ZIP mounts
- Use read-only access constants for bundled assets
- Encode provider capability (read-only) in your mount registry
When it happens
Trigger: Calling OpenStream with VirtualFileMode.Create/New/CreateNew/OpenOrCreate or VirtualFileAccess.Write/ReadWrite on a ZIP-backed provider.
Common situations: Code shared between disk and ZIP providers that opens files for writing; savegame/config writes pointed at a bundled ZIP asset mount; copying a write path from a FileSystemProvider implementation.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- You cannot modify this stream.
- File not found inside ZIP archive.
- Could not find installation path for package
- Base path must be non-empty (use null for passthrough).
- Stream cannot seek
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/9ea18c3e100dfa72.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core.IO/ZipFileSystemProvider.cs:68
filePath = null;
start = 0;
end = -1;
return false;
}
filePath = zipFile.FileName;
start = zipFileEntry.FileOffset;
end = zipFileEntry.FileOffset + zipFileEntry.FileSize;
return true;
}
public override Stream OpenStream(string url, VirtualFileMode mode, VirtualFileAccess access, VirtualFileShare share = VirtualFileShare.Read, StreamFlags streamType = StreamFlags.None)
{
if (!zipFileEntries.TryGetValue(url, out var zipFileEntry))
throw new FileNotFoundException("File not found inside ZIP archive.");
if (mode != VirtualFileMode.Open || access != VirtualFileAccess.Read)
throw new UnauthorizedAccessException("ZIP archive are read-only.");
lock (zipFile)
{
if (zipFileEntry.Method == Compression.Store)
{
// Open a VirtualFileStream on top of Zip FileStream
return new VirtualFileStream(new FileStream(zipFileEntry.ZipFileName, FileMode.Open, FileAccess.Read), zipFileEntry.FileOffset, zipFileEntry.FileOffset + zipFileEntry.FileSize);
}
// Decompress it into a MemoryStream
var buffer = new byte[zipFileEntry.FileSize];
zipFile.ExtractFile(zipFileEntry, buffer);
return new MemoryStream(buffer);
}
}
public override bool DirectoryExists(string url)
{View on GitHub (pinned to 96fad776d2)