janhq/jan · error · io::Error

String length is unreasonably large

Error message

String length {} is unreasonably large

What it means

read_gguf_string refuses any GGUF string whose u64 length prefix exceeds 1 MiB. Real GGUF strings (tensor names, KV keys, short metadata values) are tiny; a huge length means the stream has desynchronized or the file is corrupt, and allocating the buffer would be dangerous.

Solutions

  1. Re-download the file and verify its checksum
  2. Verify the file is genuine GGUF v2/v3 starting with the 'GGUF' magic
  3. Check for truncated/interleaved shards - each shard must be parsed from its own start
  4. Cross-check the file with llama.cpp's gguf_dump

Example fix

// before
let meta = read_gguf_metadata(File::open("download.bin")?)?; // huge length
// after
let bytes = std::fs::read("download.bin")?;
assert_eq!(&bytes[0..4], b"GGUF", "not a GGUF file");
let version = u32::from_le_bytes(bytes[4..8].try_into().unwrap());
assert!(version >= 2, "v1 files cannot be read as v2");
let meta = read_gguf_metadata(Cursor::new(bytes))?;
Defensive patterns

Strategy: validation

Validate before calling

fn magic_and_version_ok(bytes: &[u8]) -> bool {
    bytes.len() >= 8
        && &bytes[0..4] == b"GGUF"
        && u32::from_le_bytes(bytes[4..8].try_into().unwrap()) >= 2
}
// prevents desynchronized reads that fabricate huge string lengths

Prevention

When it happens

Trigger: Reading a GGUF file whose length prefix at the current position is > 1,048,576 - corruption, misaligned parsing (e.g. v1 file read as v2), or reading garbage bytes as a length.

Common situations: Corrupted downloads, reading a non-GGUF or v1 file as v2/v3, parsing at a wrong offset after a bad earlier record, fuzzing/malicious files.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17). Data as JSON: /api/errors/934681244c71f823. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/plugins/tauri-plugin-llamacpp/src/gguf/helpers.rs:149

) -> 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 7205d770c1)