dotnet/wpf · error · InvalidOperationException

Image_OriginalStreamReadOnly

Error message

Image_OriginalStreamReadOnly

What it means

CreateInPlaceBitmapMetadataWriter requires the decoder's underlying source stream to be writable. CheckOriginalWritable throws InvalidOperationException with Image_OriginalStreamReadOnly when the original stream or file was opened read-only, so in-place metadata editing cannot proceed.

Solutions

  1. Open the backing file with FileAccess.ReadWrite / FileShare.Read so the decoder's _isOriginalWritable is true.
  2. Fall back to non-destructive editing: copy the frame through a BitmapFrame + BitmapMetadata into a new file.
  3. Check stream.CanWrite before calling CreateInPlaceBitmapMetadataWriter.
  4. Catch InvalidOperationException and save metadata via re-encoding instead.

Example fix

// before
var fs = File.OpenRead(path); // read-only
var dec = BitmapDecoder.Create(fs, opts, BitmapCacheOption.OnLoad);
var writer = dec.CreateInPlaceBitmapMetadataWriter(); // throws
// after
using var fs = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
var dec = BitmapDecoder.Create(fs, opts, BitmapCacheOption.Default);
var writer = dec.CreateInPlaceBitmapMetadataWriter();
Defensive patterns

Strategy: type-guard

Validate before calling

static bool CanEditInPlace(string path) =>
    File.Exists(path) && new FileInfo(path).IsReadOnly == false;

Type guard

bool DecoderSupportsInPlaceWrite(BitmapDecoder d) => d.Frames.Count > 0 && d.ToString() != null && d.InternalImagesCanBeWritten; // check CanWrite on the backing stream before calling

Try / catch

try { var writer = decoder.CreateInPlaceBitmapMetadataWriter(); writer.SetQuery("/app1/ifd/exif", metadata); }
catch (InvalidOperationException) { ReEncodeWithMetadata(decoder, outputPath, metadata); }

Prevention

When it happens

Trigger: Calling decoder.CreateInPlaceBitmapMetadataWriter() when the decoder was built from a read-only FileStream, a URI with BitmapCreateOptions opened without write access, a MemoryStream that cannot be written, or a format that does not support in-place metadata updates.

Common situations: Editing EXIF/ICC metadata of images loaded from resources embedded in the assembly (read-only); files opened with FileAccess.Read; images on read-only media or without write permissions.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/47dc3228740f7723. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/BitmapDecoder.cs:991

                        }

                        _isColorContextCached = true;
                    }
                }

                return _readOnlycolorContexts;
            }
        }


        /// <summary>
        /// Checks whether the underlying source is writable (useful for in-place metadata editing)
        /// </summary>
        internal void CheckOriginalWritable()
        {
            if (!_isOriginalWritable)
            {
                throw new System.InvalidOperationException(SR.Image_OriginalStreamReadOnly);
            }
        }

        #endregion

        #region Internal/Private Methods

        internal static SafeMILHandle SetupDecoderFromUriOrStream(
            Uri uri,
            Stream stream,
            BitmapCacheOption cacheOption,
            out Guid clsId,
            out bool isOriginalWritable,
            out Stream uriStream,
            out UnmanagedMemoryStream unmanagedMemoryStream,
            out SafeFileHandle safeFilehandle
            )
        {

View on GitHub (pinned to 81131a70a4)