dotnet/wpf · error · FileFormatException
SR.InvalidStringFormat
Error message
SR.InvalidStringFormat
What it means
FileFormatException thrown by ReadLengthPrefixedString when reader.ReadBytes(length) returns fewer bytes than the declared length prefix — the stream ended prematurely. It signals a truncated string payload inside a publish/use-license stream.
Solutions
- Verify the stream is fully intact (compare against expected size/checksum) before parsing
- Re-acquire or regenerate the license data instead of parsing the damaged stream
- Restore the compound file from backup
- Check that the stream is not being consumed concurrently by another reader that advanced its position
Example fix
// before: assuming a complete stream
var license = LoadPublishLicense(packStream); // throws if truncated
// after: check completeness first
if (!packStream.CanRead || packStream.Length == 0)
throw new InvalidDataException("License stream is empty or unreadable.");
using (var buffered = new MemoryStream(ReadAllBytes(packStream)))
{
var license = LoadPublishLicense(buffered);
} Defensive patterns
Strategy: validation
Validate before calling
bool StringFitsInStream(Stream s)
{
if (s.Length - s.Position < sizeof(Int32)) return false;
long pos = s.Position;
using (var br = new BinaryReader(s, Encoding.UTF8, leaveOpen: true))
{
int len = br.ReadInt32();
bool ok = len >= 0 && s.Position + len <= s.Length;
s.Position = pos;
return ok;
}
} Try / catch
try
{
var license = LoadPublishLicense(stream);
}
catch (FileFormatException ex)
{
logger.LogError(ex, "License stream truncated: declared string length exceeds remaining bytes.");
throw new InvalidDataException("Truncated license stream; re-acquire the license.", ex);
} Prevention
- Buffer streams fully into memory before parsing so truncation is detected up front
- Verify file completeness (checksum) before opening compound files
- Avoid reading streams concurrently from multiple consumers
- Retry downloads of license-bearing files on incomplete transfer
When it happens
Trigger: Any call path through ReadLengthPrefixedString (LoadPublishLicense, LoadUserFromStream's base64UserName, LoadUseLicenseAndUserFromStream, LoadUseLicenseFromStream) where the length prefix promises N bytes but fewer than N remain in the stream.
Common situations: Truncated downloads or file copies; compound files damaged by disk errors; streams written by a buggy writer that under-counted the string length; reading a stream already positioned at/past its end.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- SR.Format(SR.ExcessiveLengthPrefix, length, maxLength)
- Document does not contain a package.
- Document does not contain any rights management-protected…
- FileFormatException
- Image_CantDealWithStream
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/6928ee7d1d2d2a54.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptionTransform.cs:1183
/// file with a huge length prefix from making us allocate all our memory.
/// </param>
private static string
ReadLengthPrefixedString(
BinaryReader reader,
Encoding encoding,
int maxLength
)
{
Int32 length = reader.ReadInt32();
if (length > maxLength)
{
throw new FileFormatException(SR.Format(SR.ExcessiveLengthPrefix, length, maxLength));
}
byte[] bytes = reader.ReadBytes(length);
if (bytes.Length != length)
{
throw new FileFormatException(SR.InvalidStringFormat);
}
string s = encoding.GetString(bytes);
SkipDwordPadding(bytes.Length, reader);
return s;
}
/// <summary>
/// Skip past the DWORD padding bytes at the end of a string of the specified length.
/// </summary>
/// <param name="length">
/// Length in bytes of the string that was read.
/// </param>
/// <param name="reader">
/// Binary reader from which the string was read.
/// </param>View on GitHub (pinned to 81131a70a4)