janhq/jan · error · io::Error
String length {} is unreasonably large
Error message
String length {} is unreasonably large What it means
Returned by `read_gguf_string` when the u64 little-endian length of a GGUF string exceeds 1 MiB (1024 * 1024 bytes). The parser refuses to allocate a buffer of that size as a guard against corrupt length fields that would cause OOM. Real GGUF metadata keys and most string values are well under this bound.
Source
Thrown at src-tauri/plugins/tauri-plugin-llamacpp/src/gguf/helpers.rs:66
) -> io::Result<(String, String)> {
let key = read_gguf_string(reader).map_err(|e| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("Failed to read key for metadata entry {}: {}", index, e),
)
})?;
let value_type_u32 = reader.read_u32::<LittleEndian>()?;
let value_type = GgufValueType::try_from(value_type_u32)?;
let value = read_gguf_value(reader, value_type)?;
Ok((key, value))
}
fn read_gguf_string<R: Read + ReadBytesExt>(reader: &mut R) -> io::Result<String> {
let len = reader.read_u64::<LittleEndian>()?;
if len > (1024 * 1024) {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("String length {} is unreasonably large", len),
));
}
let mut buf = vec![0u8; len as usize];
reader.read_exact(&mut buf)?;
String::from_utf8(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
}
fn read_gguf_value<R: Read + Seek + ReadBytesExt>(
reader: &mut R,
value_type: GgufValueType,
) -> io::Result<String> {
match value_type {
GgufValueType::Uint8 => Ok(reader.read_u8()?.to_string()),
GgufValueType::Int8 => Ok(reader.read_i8()?.to_string()),
GgufValueType::Uint16 => Ok(reader.read_u16::<LittleEndian>()?.to_string()),
GgufValueType::Int16 => Ok(reader.read_i16::<LittleEndian>()?.to_string()),View on GitHub (pinned to fad3f12a14)
Solutions
- Check stream alignment: confirm the immediately preceding value was read with the correct width per the GGUF spec.
- If the field is legitimately a large string (chat template, tokenizer data), raise the cap to e.g. 16 MiB and re-test.
- Hex-dump the region around the failure to confirm whether the length bytes look like a plausible ASCII-size value or random garbage.
- If the file is corrupted, re-download from a trusted source.
Example fix
// before
if len > (1024 * 1024) {
return Err(io::Error::new(InvalidData, format!("String length {} is unreasonably large", len)));
}
// after - larger cap plus alignment hint in the message
const MAX_STR_LEN: u64 = 16 * 1024 * 1024;
if len > MAX_STR_LEN {
let pos = reader.stream_position().unwrap_or(0);
return Err(io::Error::new(InvalidData,
format!("string len {} at byte {} exceeds cap {} (likely misalignment)", len, pos, MAX_STR_LEN)));
} Defensive patterns
Strategy: validation
Validate before calling
fn plausibly_aligned(reader: &mut impl BufRead) -> bool {
// heuristic: peek the next u64 length; if huge, the stream is likely misaligned
if let Ok(len) = reader.read_u64::<LittleEndian>() { len <= 1024 * 1024 } else { false }
} Type guard
null
Try / catch
match read_gguf_string(reader) {
Ok(s) => Ok(s),
Err(e) if e.to_string().contains("unreasonably large") => {
Err(CorruptFile("oversized string length".into()))
}
Err(e) => Err(e.into()),
} Prevention
- Validate stream alignment by re-deriving offsets from the spec before reading each field.
- Cross-check the file's metadata_count against expected ranges for the model family.
- Verify checksums before parsing.
When it happens
Trigger: Reading a metadata key or string value whose length field decodes to a value greater than 1,048,576. This typically means the byte stream is misaligned (a previous field was read with the wrong width) or the length bytes themselves are corrupted. It can also fire on a maliciously crafted file designed to OOM the reader, though the cap defeats that.
Common situations: Stream misalignment after an array element was skipped with the wrong stride; an endianness mismatch on the length field; a quantized file from a buggy converter that wrote the wrong length. Rarely, a legitimately huge string value (e.g. a tokenizer chat template) could approach 1 MiB, in which case the cap is too tight.
Related errors
- <Utf8Error>
- Array length {} is unreasonably large
- Not a GGUF file
- Failed to read key for metadata entry {}: {}
- Unknown GGUF value type: {}
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/934681244c71f823.
Report an issue: GitHub.