dotnet/machinelearning · error · InvalidDataException
Unexpected end of data while skipping varint.
Error message
Unexpected end of data while skipping varint.
What it means
Thrown by SkipField when handling wire type 0 (varint): a continuation byte is required (high bit set) but pos >= end, so the unknown field's varint cannot be fully skipped. The library must consume the whole value to stay synchronized with the protobuf stream; it throws when the data ends too early.
Source
Thrown at src/Microsoft.ML.Tokenizers/SentencepieceModel.cs:121
buffer[2] = data[pos + 1];
buffer[3] = data[pos];
value = BitConverter.ToSingle(buffer, 0);
}
pos += 4;
return value;
}
internal static void SkipField(byte[] data, int end, int wireType, ref int pos)
{
switch (wireType)
{
case 0: // varint (max 10 bytes per protobuf spec)
for (int i = 0; i < 10; i++)
{
if (pos >= end)
{
throw new InvalidDataException("Unexpected end of data while skipping varint.");
}
if ((data[pos++] & 0x80) == 0)
{
break;
}
if (i == 9)
{
throw new InvalidDataException("Malformed varint.");
}
}
break;
case 1: // 64-bit fixed
if (pos > end - 8)
{
throw new InvalidDataException("Unexpected end of data while skipping fixed64.");View on GitHub (pinned to 7b76e69cf9)
Solutions
- Re-download/verify the complete model file — the parse cannot recover from a mid-field truncation.
- Regenerate the model with a compatible SentencePiece version if unknown-field handling matters to you.
- Ensure the whole file is read into memory before parsing (no partial reads).
- Add a checksum check before tokenizer construction to detect truncation early.
Example fix
// before
var tokenizer = SentencePieceTokenizer.Create(truncatedStreamBytes);
// after
byte[] bytes = ReadAllBytesFully(stream); // loop until EOF
if (!ChecksumMatches(bytes))
throw new InvalidDataException("Tokenizer model incomplete; re-download.");
var tokenizer = SentencePieceTokenizer.Create(bytes); Defensive patterns
Strategy: try-catch
Validate before calling
// Detect truncation cheaply before loading:
if (modelBytes.Length == 0 || modelBytes[^1] == 0x80) // ends mid-continuation byte
throw new InvalidDataException("Model appears truncated (ends on a varint continuation byte)."); Try / catch
try { tokenizer = SentencePieceTokenizer.Create(modelBytes); }
catch (InvalidDataException ex)
{ throw new InvalidDataException("Could not skip an unknown field: model stream is truncated or from an incompatible protobuf version.", ex); } Prevention
- Regenerate models with a SentencePiece version compatible with your library
- Verify checksums before construction so truncation is caught early
- Read complete files; avoid partial reads from network streams
- Log the model file path and size in the failure message to speed diagnosis
When it happens
Trigger: SkipField encounters an unknown field with wire type 0, iterates up to 10 varint bytes, and hits the end of the buffer before a byte with the continuation bit clear. Triggered by truncated models containing fields (e.g. newer ModelProto fields like trainer_spec variants) that must be skipped.
Common situations: Model serialized by a newer SentencePiece/protobuf version includes unknown fields; the (truncated) file ends inside such a field; partial downloads landing mid-unknown-field; binary corruption extending a varint past the buffer.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- Unexpected end of data while reading varint.
- Invalid length-delimited field size.
- Unexpected end of data while reading float.
- Unexpected end of data while skipping fixed64.
- Unexpected end of data while skipping fixed32.
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/146dc298c722fa62.
Report an issue: GitHub.