dotnet/wpf · error · FileFormatException
SR.CFRCorruptStgFollowStm
Error message
SR.CFRCorruptStgFollowStm
What it means
While Load walks the reference's path segments, storage and stream components must be ordered storages-first, stream-last. A Storage entry appearing after a stream name means the path is malformed (nothing can live under a stream), so Load throws FileFormatException(SR.CFRCorruptStgFollowStm).
Solutions
- Regenerate the package from its source — the serialized path is structurally invalid.
- Check the producing writer's reference serialization for storage/stream ordering bugs.
- If parsing third-party files, reject them up front with your own structural validation.
- Diff the record bytes against a known-good reference to find where ordering broke.
Example fix
// before: blind deserialization of untrusted references var r = CompoundFileReference.Load(binaryReader); // after: pre-validate ordering of path components ValidateReferencePathOrder(rawBytes); // storage... then stream last var r = CompoundFileReference.Load(binaryReader);
Defensive patterns
Strategy: validation
Validate before calling
bool PathOrderIsValid(IList<(bool isStorage)> segs) { bool sawStream = false; foreach (var s in segs) { if (!s.isStorage) sawStream = true; else if (sawStream) return false; } return true; } Try / catch
try { var r = CompoundFileReference.Load(reader); } catch (FileFormatException) { RejectMalformedReference(source); } Prevention
- Ensure writers serialize storages before stream names
- Structurally validate third-party compound files before load
- Fuzz-test your own writer's reference serialization
When it happens
Trigger: Load reads a RefComponentType.Storage entry after already having read a stream name — i.e. the serialized path looks like \storage\stream\storage. Caused by corrupt data or a writer emitting entries in the wrong order.
Common situations: Hand-crafted or fuzzed compound files; writers that serialize path segments out of order; byte-level corruption reordering records; mixed-version writer/reader format drift.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- SR.CFRCorrupt
- Signature structures are corrupted in this package.
- SR.CorruptStream
- SR.PackageSignatureCorruption
- SR.UseLicenseStreamCorrupt
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/143a396364ddf5c3.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CompoundFileReference.cs:190
// type is encountered
StringCollection storageList = null;
String streamName = null;
// loop through the entries - accumulating strings until we know what kind of object
// we ultimately need
int byteLength; // reusable
while (entryCount > 0)
{
// first Int32 tells us what kind of component this entry represents
RefComponentType refType = (RefComponentType)reader.ReadInt32();
bytesRead += ContainerUtilities.Int32Size;
switch (refType)
{
case RefComponentType.Storage:
{
if (streamName != null)
throw new FileFormatException(
SR.CFRCorruptStgFollowStm);
if (storageList == null)
storageList = new StringCollection();
String str = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out byteLength);
bytesRead += byteLength;
storageList.Add(str);
} break;
case RefComponentType.Stream:
{
if (streamName != null)
throw new FileFormatException(
SR.CFRCorruptMultiStream);
streamName = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out byteLength);
bytesRead += byteLength;
} break;View on GitHub (pinned to 81131a70a4)