dotnet/wpf · error · FileFormatException

Image_CantDealWithUri

Error message

Image_CantDealWithUri

What it means

BitmapDecoder's URI constructor sniffs the file and verifies the underlying WIC decoder CLSID matches the decoder type being constructed. If the decoded image's actual format differs from the expected CLSID (e.g. asking for a PngBitmapDecoder on a JPEG file), a FileFormatException with Image_CantDealWithUri is thrown.

Solutions

  1. Use the generic BitmapDecoder.Create(uri, createOptions, cacheOption) and let WIC auto-detect the format instead of a format-specific subclass.
  2. Verify the file's actual format (magic bytes / extension) matches the decoder type you construct.
  3. Re-export or convert the image so its container matches the decoder you are using.
  4. Catch FileFormatException and fall back to generic BitmapDecoder.Create.

Example fix

// before
var dec = new PngBitmapDecoder(new Uri(path), BitmapCreateOptions.None, BitmapCacheOption.OnLoad); // throws if not PNG
// after
var dec = BitmapDecoder.Create(new Uri(path), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
Defensive patterns

Strategy: try-catch

Validate before calling

static string SniffImageFormat(string path)
{
    var b = File.ReadAllBytes(path);
    if (b.Length > 8 && b[0] == 0x89 && b[1] == (byte)'P') return "png";
    if (b.Length > 3 && b[0] == 0xFF && b[1] == 0xD8) return "jpeg";
    if (b.Length > 3 && b[0] == (byte)'G' && b[1] == (byte)'I' && b[2] == (byte)'F') return "gif";
    return "unknown";
}

Type guard

bool MatchesDecoder(Uri uri, Type decoderType) =>
    SniffImageFormat(uri.IsFile ? uri.LocalPath : null) == decoderType.Name.Replace("BitmapDecoder", "").ToLowerInvariant();

Try / catch

try { decoder = new PngBitmapDecoder(uri, opts, cache); }
catch (FileFormatException) { decoder = BitmapDecoder.Create(uri, opts, cache); }

Prevention

When it happens

Trigger: Calling e.g. BitmapDecoder.Create with a mismatched derived decoder (new PngBitmapDecoder(uri, ...) on a non-PNG file), or a URI whose content WIC resolves to a different decoder CLSID than expectedClsId.

Common situations: Files renamed to the wrong extension without conversion; byte streams served with wrong content; mixed-format image folders processed with one decoder type; corrupted file headers causing WIC to detect a different format.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

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

                    bitmapUri,
                    null,
                    cacheOption,
                    out clsId,
                    out isOriginalWritable,
                    out _uriStream,
                    out _unmanagedMemoryStream,
                    out _safeFilehandle
                    );

                if (_uriStream == null)
                {
                    GC.SuppressFinalize(this);
                }
            }

            if (clsId != expectedClsId)
            {
                throw new FileFormatException(bitmapUri, SR.Image_CantDealWithUri);
            }

            _uri = bitmapUri;
            _createOptions = createOptions;
            _cacheOption = cacheOption;
            _syncObject = _decoderHandle;
            _isOriginalWritable = isOriginalWritable;
            Initialize(decoder);
        }

        /// <summary>
        /// Constructor
        /// </summary>
        internal BitmapDecoder(
            Stream bitmapStream,
            BitmapCreateOptions createOptions,
            BitmapCacheOption cacheOption,
            Guid expectedClsId

View on GitHub (pinned to 81131a70a4)