dotnet/wpf · error · ArgumentException
Invalid ISF data
Error message
Invalid ISF data
What it means
Thrown by StrokeSerializer.DecodeISFIntoStroke when a stroke's decoded property data size (propsize) exceeds the remaining bytes in the stroke block of the ISF stream. The decoder would otherwise read past the block boundary, so it rejects the input as corrupt.
Solutions
- Validate the ISF file integrity (complete header, sizes) before calling Deserialize
- Re-export the ink from the source application rather than deserializing the damaged file
- Ensure the stream is seekable and positioned at the ISF payload start
- Catch ArgumentException from Deserialize and degrade gracefully (drop the corrupt stroke)
- If writing ISF, ensure each property-block size field equals the exact compressed byte count
Example fix
// before
try { scs.Deserialize(suspectStream); }
// after
try { scs.Deserialize(suspectStream); }
catch (ArgumentException ex) {
log.Warn("Corrupt ISF stroke data discarded", ex);
strokeCollection = new StrokeCollection(); // degrade gracefully
} Defensive patterns
Strategy: try-catch
Validate before calling
// sanity check: ISF must be complete; verify declared block sizes fit in stream static bool IsCompleteIsf(Stream s) => s.CanSeek && s.Length >= 8;
Try / catch
try { scs.Deserialize(stream); }
catch (ArgumentException ex) {
log.Warn("ISF stroke property size exceeds block", ex);
strokeCollection = LoadBackupInk() ?? new StrokeCollection();
} Prevention
- Verify file integrity (checksum/length) before deserializing ink
- Never hand-build ISF block size fields; use the serializer for writing
- Handle per-stroke failures gracefully instead of failing the whole collection
When it happens
Trigger: Deserializing an ISF stream where an embedded stroke attribute/property block claims a compressed payload larger than the declared stroke-block remainder — truncated files, corrupted streams, or malformed hand-built ISF.
Common situations: Loading ink files damaged in storage/transfer; ISF produced by non-Windows or third-party ink tools with inconsistent size headers; passing a mispositioned stream so size headers are misread.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Drawing Attribute tag embedded in ISF stream does not match…
- ExtendedProperty decoded totalBytesInStrokeBlockOfIsfStream…
- Invalid PenTip value found in ISF stream
- InvalidDataInISF
- ISF Operation Failed
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/8366a1f6363be162.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/StrokeSerializer.cs:279
if (locallyDecodedBytes > remainingBytesInStrokeBlock)
throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
remainingBytesInStrokeBlock -= locallyDecodedBytes;
uint propsize;
locallyDecodedBytes = SerializationHelper.Decode(stream, out propsize);
if (locallyDecodedBytes > remainingBytesInStrokeBlock)
throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
remainingBytesInStrokeBlock -= locallyDecodedBytes;
// Compressed data totalBytesInStrokeBlockOfIsfStream
propsize += 1;
// Make sure we have enough data to read
if (propsize > remainingBytesInStrokeBlock)
throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
byte[] in_buffer = new byte[propsize];
uint bytesRead = StrokeCollectionSerializer.ReliableRead(stream, in_buffer, propsize);
if (propsize != bytesRead)
{
throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Read different size from stream then expected"));
}
byte[] out_buffer = Compressor.DecompressPropertyData(in_buffer);
System.Diagnostics.Debug.Fail("ExtendedProperties for points are not supported");
// skip the bytes in both success & failure cases
// Note: Point ExtendedProperties are discarded
remainingBytesInStrokeBlock -= propsize;
}
}View on GitHub (pinned to 81131a70a4)