{"record":{"id":"496d872b9fbbc030","repo":"dotnet/wpf","slug":"sr-versionstreammissing","errorCode":null,"errorMessage":"SR.VersionStreamMissing","messagePattern":"SR\\.VersionStreamMissing","errorType":"exception","errorClass":"FileFormatException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/VersionedStreamOwner.cs","lineNumber":303,"sourceCode":"        /// Callback for when a Stream is read from\n        /// </summary>\n        /// <remarks>Can modify the FormatVersion stream pointer.</remarks>\n        /// <param name=\"throwIfEmpty\">caller requires an existing FormatVersion</param>\n        internal void ReadAttempt(bool throwIfEmpty)\n        {\n            CheckDisposed();    // central location\n\n            // only do this once\n            if (!_readOccurred)\n            {\n                // read\n                EnsureParsed();\n\n                // first usage?\n                if (throwIfEmpty || BaseStream.Length > 0)\n                {\n                    if (_fileVersion == null)\n                        throw new FileFormatException(SR.VersionStreamMissing);\n\n                    // compare versions\n                    // verify we can read this version\n                    if (!_fileVersion.IsReadableBy(_codeVersion.ReaderVersion))\n                    {\n                        throw new FileFormatException(\n                                        SR.Format(\n                                            SR.ReaderVersionError,\n                                            _fileVersion.ReaderVersion,\n                                            _codeVersion\n                                            )\n                                        );\n                    }\n                }\n                _readOccurred = true;\n            }\n        }\n","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/VersionedStreamOwner.cs#L285-L321","documentation":"FileFormatException (SR.VersionStreamMissing) thrown by VersionedStreamOwner.ReadAttempt when the stream requires a version header but none was found (_fileVersion == null): either throwIfEmpty was requested on an empty stream, or the stream has data but no persisted FormatVersion. Versioned compound-file streams must start with a version block identifying reader/updater versions.","triggerScenarios":"Reading from a versioned stream that contains no FormatVersion header — e.g. the stream was created by non-versioned code, the header was overwritten/truncated, or Read/ReadByte was called with throwIfEmpty=true on a zero-length stream.","commonSituations":"Opening a plain (non-versioned) file through the versioned-stream path; files damaged at the header; a writer that crashed before persisting the version block; mixing legacy and versioned compound-file formats.","solutions":["Ensure the stream was created through the versioned-stream writer so the FormatVersion header is persisted first","Regenerate or restore the file — a missing header cannot be repaired by reading","If an empty stream is legitimate, use the non-throwing path (throwIfEmpty=false) instead of the strict read entry point","Detect the format before opening: check for the version signature and use a plain stream when absent"],"exampleFix":"// before: strict read on a possibly headerless/empty stream\nint n = versionedStream.Read(buffer, 0, buffer.Length); // VersionStreamMissing\n// after: probe for data before the strict read\nif (versionedStream.Length == 0)\n{\n    return 0; // legitimately empty\n}\nint n = versionedStream.Read(buffer, 0, buffer.Length);","handlingStrategy":"validation","validationCode":"static bool HasVersionHeader(Stream s)\n{\n    if (s.Length < MinVersionBlockSize) return false;\n    long pos = s.Position;\n    byte[] magic = new byte[VersionMagic.Length];\n    int n = s.Read(magic, 0, magic.Length);\n    s.Position = pos;\n    return n == magic.Length && magic.AsSpan().SequenceEqual(VersionMagic);\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    int n = versionedStream.Read(buffer, 0, buffer.Length);\n}\ncatch (FileFormatException ex) when (ex.Message.Contains(\"version\"))\n{\n    // no FormatVersion present: handle as legacy/plain data or reject\n    HandleAsUnversionedData();\n}","preventionTips":["Always create versioned streams via the library's writer so the header is persisted first","Detect unversioned files before routing them into the versioned-stream path","Validate file headers after any crash-prone write operation","Keep backups of files whose version block might be damaged"],"tags":["versioning","file-format","missing-header","wpf"],"backgroundTag":"schema-validation-failed","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}