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

  1. Use VirtualFileMode.Open with VirtualFileAccess.Read when reading from ZIP providers.
  2. Redirect write operations to a writable FileSystemProvider mount instead of the ZIP.
  3. Guard writes: check the provider type (is ZipFileSystemProvider) and route to a writable provider.
  4. 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

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


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)