icsharpcode/ILSpy · error · InvalidDataException
Invalid BAML signature length.
Error message
Invalid BAML signature length.
What it means
Thrown by BamlReader.ReadSignature after reading the 4-byte length prefix of the BAML signature. The check len >> 1 != MSBAML_SIG.Length guards against a crafted length value before any allocation, because the only accepted signature is the fixed 6-char 'MSBAML'. A mismatch means the stream is not valid BAML or has been tampered with.
Source
Thrown at ICSharpCode.BamlDecompiler/Baml/BamlReader.cs:71
return false;
var sig = new string(rdr.ReadChars(len));
return sig == MSBAML_SIG;
}
finally
{
str.Position = pos;
}
}
static string ReadSignature(Stream str)
{
var rdr = new BinaryReader(str, Encoding.Unicode);
uint len = rdr.ReadUInt32();
// len is read straight from the file, before the MSBAML_SIG check below. The only
// accepted signature is the fixed-length "MSBAML", so reject any other length here
// rather than allocating an attacker-sized string from a crafted value.
if (len >> 1 != (uint)MSBAML_SIG.Length)
throw new InvalidDataException("Invalid BAML signature length.");
var sig = new string(rdr.ReadChars((int)(len >> 1)));
rdr.ReadBytes((int)(((len + 3) & ~3) - len));
return sig;
}
public static BamlDocument ReadDocument(Stream str, CancellationToken token)
{
var ret = new BamlDocument();
var reader = new BamlBinaryReader(str);
ret.Signature = ReadSignature(str);
if (ret.Signature != MSBAML_SIG)
throw new NotSupportedException();
ret.ReaderVersion = new BamlDocument.BamlVersion { Major = reader.ReadUInt16(), Minor = reader.ReadUInt16() };
ret.UpdaterVersion = new BamlDocument.BamlVersion { Major = reader.ReadUInt16(), Minor = reader.ReadUInt16() };
ret.WriterVersion = new BamlDocument.BamlVersion { Major = reader.ReadUInt16(), Minor = reader.ReadUInt16() };
if (ret.ReaderVersion.Major != 0 || ret.ReaderVersion.Minor != 0x60 ||
ret.UpdaterVersion.Major != 0 || ret.UpdaterVersion.Minor != 0x60 ||
ret.WriterVersion.Major != 0 || ret.WriterVersion.Minor != 0x60)
View on GitHub (pinned to 60c08fcb74)
Solutions
- Make sure you are feeding the actual BAML resource stream (e.g. the entry from a .g.resources stream), not the whole assembly.
- Probe the stream first with BamlReader.IsBamlHeader, which performs the same length/signature check non-destructively.
- If the resource is corrupt, re-obtain it from the original assembly.
Example fix
// before
using var fs = File.OpenRead(path);
var doc = BamlReader.ReadDocument(fs, ct); // throws if `path` is not a BAML stream
// after
using var fs = File.OpenRead(path);
if (!BamlReader.IsBamlHeader(fs))
throw new InvalidDataException("Selected stream is not MSBAML.");
fs.Position = 0;
var doc = BamlReader.ReadDocument(fs, ct); Defensive patterns
Strategy: validation
Validate before calling
// call before ReadDocument
public static bool IsLikelyBaml(Stream str)
{
return BamlReader.IsBamlHeader(str); // restores position itself
} Try / catch
try {
var doc = BamlReader.ReadDocument(stream, token);
} catch (InvalidDataException ex) when (ex.Message.Contains("signature length")) {
// not a BAML stream; pick the correct resource instead
} Prevention
- Always resolve the .baml entry from the .g.resources stream rather than passing an assembly or arbitrary file.
- Use IsBamlHeader as a cheap pre-check at the trust boundary.
When it happens
Trigger: ReadDocument is given a stream whose first uint (the signature length, stored as char-count<<1) is not exactly 12 (i.e. 6 chars). Typical when the stream is a plain PE/assembly, a managed resource that is not BAML, or arbitrary bytes.
Common situations: Pointing the BAML decompiler at a whole .NET DLL instead of the embedded BAML resource; selecting a non-BAML resource entry; corrupted/garbled BAML; an attacker-crafted stream with a huge length value.
Related errors
- BAML defer record points at an offset that is not a record b
- Unexpected footer.
- {type}
- {ser}
- Unknown double type.
AI-assisted analysis of icsharpcode/ILSpy@60c08fcb74 (2026-08-13).
Data as JSON: /api/errors/507f620f27434a54.
Report an issue: GitHub.