dotnet/wpf · error · FileFormatException

SR.Format(SR.UpdaterVersionError…

Error message

SR.Format(SR.UpdaterVersionError, _fileVersion.UpdaterVersion, _codeVersion)

What it means

FileFormatException (SR.UpdaterVersionError) thrown by VersionedStreamOwner.WriteAttempt when the version header already in the stream (_fileVersion.UpdaterVersion) is not updatable by the running code's version (_codeVersion.UpdaterVersion). It prevents writing data with a format newer than this code is allowed to produce — a forward-compatibility guard for compound-file versioned streams.

Solutions

  1. Open the file read-only instead of for update, or copy it to a new file if writes are required
  2. Upgrade the runtime/library so its updater version matches or exceeds the file's version
  3. Rewrite the file with a compatible writer version before performing updates
  4. Catch FileFormatException around update attempts and route the file through a migration path

Example fix

// before: opening for update regardless of the file's version
using (var fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
{
    versionedStream.Write(data, 0, data.Length); // UpdaterVersionError
}
// after: open read-only when only reading, or handle the version mismatch
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
    versionedStream.Read(buffer, 0, buffer.Length); // reads are governed by ReaderVersion instead
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Open the file only for reading if updates are not strictly required
bool canAttemptUpdate = CanOpenReadWrite(path) && FileWasWrittenByCompatibleWriter(path); // compare recorded UpdaterVersion with your runtime's

Try / catch

try
{
    versionedStream.Write(data, 0, data.Length);
}
catch (FileFormatException ex) when (ex.Message.Contains("update") || ex.Message.Contains("version"))
{
    // fall back: copy to a new file and rewrite, or ask the user to upgrade
    CopyAndRewriteWithCompatibleWriter();
}

Prevention

When it happens

Trigger: Attempting Write, WriteByte, or SetLength on a versioned compound-file stream whose persisted FormatVersion carries an UpdaterVersion newer than the library's allowed updater version (e.g. the file was last written by a substantially newer runtime/tool).

Common situations: Files created by a newer .NET/WPF version opened for update by an older runtime; files round-tripped through different tools; deployment rollout skew where some machines run older runtimes against files written by newer ones.

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/c4c2237ad56ca1a2. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/VersionedStreamOwner.cs:257

        {
            CheckDisposed();    // central location

            if (!_writeOccurred)
            {
                // first try to read the format version
                EnsureParsed();

                if (_fileVersion == null)
                {
                    // stream is empty so write our version
                    PersistVersion(_codeVersion);
                }
                else
                {
                    // file version found - ensure we are able to update it
                    if (!_fileVersion.IsUpdatableBy(_codeVersion.UpdaterVersion))
                    {
                        throw new FileFormatException(
                                        SR.Format(
                                            SR.UpdaterVersionError,
                                            _fileVersion.UpdaterVersion,
                                            _codeVersion
                                            )
                                        );
                    }

                    // if our version is different than previous
                    // updater then "update" the updater
                    if (_codeVersion.UpdaterVersion != _fileVersion.UpdaterVersion)
                    {
                        _fileVersion.UpdaterVersion = _codeVersion.UpdaterVersion;
                        PersistVersion(_fileVersion);
                    }
                }

                _writeOccurred = true;

View on GitHub (pinned to 81131a70a4)