dotnet/wpf · error · FileFormatException
SR.EncryptedDataStreamCorrupt
Error message
SR.EncryptedDataStreamCorrupt
What it means
ParseStreamLength reads a length prefix (the encrypted-stream length stored at the head of the on-disk data) from the base stream. If a nonzero prefix is present but shorter than the legal prefix size (_prefixLengthSize), the file's encrypted data stream is malformed, and a FileFormatException with SR.EncryptedDataStreamCorrupt is thrown. This is a data-corruption signal, not an argument error.
Solutions
- Restore the file from a known-good backup or re-acquire/re-download the document — a corrupt prefix cannot be repaired in place.
- Verify file integrity (compare size/hash against the source) to confirm the truncation.
- Re-create the rights-managed document by republishing the content with RM protection from the original material.
- Ensure storage/transfer completes atomically (write to temp then move) to prevent partial writes in the future.
- Catch FileFormatException when opening untrusted documents and degrade gracefully with a 'file is corrupt' user message.
Example fix
// before
var stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider);
// after
try
{
var stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider);
}
catch (FileFormatException)
{
Console.WriteLine("The rights-managed document's data stream is corrupt; restore from backup.");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Sanity-check file size before opening
var fi = new FileInfo(path);
if (fi.Length < RightsManagementEncryptedStreamMinHeaderSize)
throw new FileFormatException("File too small to contain a valid encrypted stream header."); Type guard
bool PlausibleEncryptedStreamLength(FileInfo fi, int prefixLengthSize)
=> fi.Exists && fi.Length >= prefixLengthSize; Try / catch
try { stream = new RightsManagementEncryptedStream(baseStream, cryptoProvider); }
catch (FileFormatException)
{ /* mark document as corrupt, offer restore/re-download */ } Prevention
- Verify file size/hash after download or copy before opening.
- Write large files atomically (temp file + rename) to avoid truncated headers.
- Catch FileFormatException at the document-open boundary and surface a recoverable UX path.
- Back up rights-managed documents; corrupt prefixes are not repairable in place.
When it happens
Trigger: Opening a rights-managed compound file whose stream-length prefix was truncated or overwritten (partial write, bad sector, faulty tool edit) so that bytesRead > 0 but bytesRead < _prefixLengthSize.
Common situations: Files truncated by interrupted downloads or copy operations; documents damaged by disk errors; hand-edited or incorrectly re-saved compound files; content migrated across tools that mangled the package header.
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
- ArgumentOutOfRangeException(authentication)
- ArgumentOutOfRangeException(authenticationType)
- ArgumentOutOfRangeException(name)
- ArgumentOutOfRangeException(right)
- ArgumentOutOfRangeException(user)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/39d78dfcf349366a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptedStream.cs:332
// seek to the beginning of the stream
_baseStream.Seek(0, SeekOrigin.Begin);
// read the size prefix
byte[] prefixData = new byte[_prefixLengthSize];
int bytesRead = PackagingUtilities.ReliableRead
(_baseStream, prefixData, 0, prefixData.Length);
// decode length data (from the prefix)
if (bytesRead == 0)
{
// probably a new stream - just assume length is zero
_streamOnDiskLength = 0;
}
else
if (bytesRead < _prefixLengthSize)
{
// not zero and shorter than legal length == corrupt file
throw new FileFormatException(SR.EncryptedDataStreamCorrupt);
}
else
{
checked
{
// This will throw on a negative value so we need not
// explicitly check for that
_streamOnDiskLength = (long)BitConverter.ToUInt64(prefixData, 0);
}
}
_streamCachedLength = _streamOnDiskLength;
}
}
private int InternalRead(long streamPosition, byte[] buffer, int offset, int count)
{
// use the explicitly passed in Position or reading in the stream
// we do not want to rely and change the real stream position View on GitHub (pinned to 81131a70a4)