dotnet/wpf · error · FileFormatException
SR.Format(SR.PublishLicenseStreamHeaderTooLong, headerLen…
Error message
SR.Format(SR.PublishLicenseStreamHeaderTooLong, headerLen, MaxPublishLicenseHeaderLen)
What it means
LoadPublishLicense enforces a maximum publish-license header size (MaxPublishLicenseHeaderLen). If the header length Int32 read from the instance data stream exceeds that bound, the header is considered implausible/malicious or from an incompatible future format, and FileFormatException(SR.Format(SR.PublishLicenseStreamHeaderTooLong, headerLen, MaxPublishLicenseHeaderLen)) is thrown with the offending and maximum lengths.
Solutions
- Open the document with a library/runtime version at least as new as the one that wrote it, so longer headers are understood.
- Inspect the first Int32 of the RM instance data stream to confirm the header length; if implausibly large, the file is corrupt — restore from backup.
- Re-publish the document from the source application with a compatible RM stack to regenerate a standard header.
- Catch FileFormatException and report the header-too-long condition (the message includes actual vs max length) to diagnostics.
- Do not attempt to patch the length field manually; regenerate the protected document instead.
Example fix
// before: no length sanity check on untrusted data
int headerLen = binaryReader.ReadInt32();
ReadBytes(binaryReader, headerLen);
// after: bound-check before allocating/reading
int headerLen = binaryReader.ReadInt32();
if (headerLen > MaxPublishLicenseHeaderLen)
{
throw new InvalidDataException(
$"Publish license header too long: {headerLen} > {MaxPublishLicenseHeaderLen}. " +
"File may be from a newer format or corrupt.");
} Defensive patterns
Strategy: validation
Validate before calling
// sanity-check the declared header length against a sane maximum
stream.Seek(0, SeekOrigin.Begin);
Span<byte> buf = stackalloc byte[4];
int headerLen = stream.Read(buf) == 4 ? BitConverter.ToInt32(buf) : 0;
if (headerLen > MaxPublishLicenseHeaderLen)
throw new InvalidDataException($"Header length {headerLen} exceeds max {MaxPublishLicenseHeaderLen}; file from newer format or corrupt."); Type guard
static bool HeaderLengthInBounds(Stream s, int maxLen)
{
long pos = s.Position;
Span<byte> b = stackalloc byte[4];
int v = s.Read(b) == 4 ? BitConverter.ToInt32(b) : int.MaxValue;
s.Seek(pos, SeekOrigin.Begin);
return v >= sizeof(int) && v <= maxLen;
} Try / catch
try
{
publishLicense = transform.LoadPublishLicense();
}
catch (FileFormatException ex) when (ex.Message.Contains("too long"))
{
log.Warn("Publish license header exceeds supported length; try a newer runtime or re-publish the document.", ex);
throw;
} Prevention
- Open protected documents with a runtime at least as new as the writer.
- Reject implausibly large length fields early when parsing untrusted streams.
- Never allocate buffers directly from untrusted length prefixes without bounds checks.
- Keep the RM/WPF stack updated to support newer header extensions.
When it happens
Trigger: Reading a rights-managed document whose instance data stream starts with an Int32 header length greater than MaxPublishLicenseHeaderLen — produced by a newer format version, by corruption of the length field, or by a deliberately crafted file.
Common situations: Opening a document created by a future/newer WPF RM writer with extended headers; a corrupted length field (e.g. pointer bytes read as Int32); fuzzed or malicious files that set an enormous length value; mixing files between incompatible RM implementations.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Document does not contain a package.
- Document does not contain any rights management-protected…
- SR.PublishLicenseStreamCorrupt
- Document contains multiple Rights Management Encryption…
- Signature structures are corrupted in this package.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/3ffad1fa8be69806.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptionTransform.cs:130
// TODO: Use leaveOpen ctor
BinaryReader utf8Reader = new BinaryReader(_publishLicenseStream, Encoding.UTF8);
//
// There follows a variable-length header (not to be confused with the physical
// stream header). This header allows future expansion, in case we want to store
// something in addition to the publish license in the primary instance data stream
// for this transform. The first field in the header is the header length in bytes
// (including the headerLen field itself).
//
Int32 headerLen = utf8Reader.ReadInt32();
if (headerLen < CU.Int32Size)
{
throw new FileFormatException(SR.PublishLicenseStreamCorrupt);
}
if (headerLen > MaxPublishLicenseHeaderLen)
{
throw new FileFormatException(
SR.Format(SR.PublishLicenseStreamHeaderTooLong,
headerLen,
MaxPublishLicenseHeaderLen
));
}
//
// Save any additional bytes in the header that we don't recognize, so we can
// write them back out later if necessary. We've already read the headerLen field,
// so subtract the size of that field from the amount we have to save.
//
// No need to use checked{} here since we already made sure that header length is greater than Int32Size
Int32 numPublishLicenseHeaderExtraBytes = headerLen - CU.Int32Size;
if (numPublishLicenseHeaderExtraBytes > 0)
{
_publishLicenseHeaderExtraBytes = new byte [numPublishLicenseHeaderExtraBytes];
if (PackagingUtilities.ReliableRead(_publishLicenseStream, _publishLicenseHeaderExtraBytes, 0, numPublishLicenseHeaderExtraBytes)
!= numPublishLicenseHeaderExtraBytes)View on GitHub (pinned to 81131a70a4)