janhq/jan · error · io::Error

Array length is unreasonably large

Error message

Array length {} is unreasonably large

What it means

read_gguf_value rejects a GGUF array KV value whose element count exceeds 1,000,000. Large real arrays (e.g. tokenizer vocabularies) exist but are normally far below this; a bigger length indicates corruption or a desynchronized walk, so the parser bails instead of looping or seeking billions of bytes.

Solutions

  1. Re-download the model file and verify its checksum
  2. Inspect the KV section with llama.cpp's gguf_dump to find the malformed array entry
  3. Check whether the parser desynchronized earlier (nested 'Error reading metadata entry' messages)
  4. If you legitimately need larger arrays, raise the 1,000,000 bound in read_gguf_value and rebuild

Example fix

// before
let meta = read_gguf_metadata(File::open("corrupt.gguf")?)?;
// after
let digest = sha256_file("corrupt.gguf")?;
assert_eq!(digest, publisher_sha256, "file corrupt - re-download");
let meta = read_gguf_metadata(File::open("corrupt.gguf")?)?;
Defensive patterns

Strategy: try-catch

Try / catch

match read_gguf_metadata(file) {
    Err(e) if e.to_string().contains("Array length") => {
        eprintln!("GGUF KV array corrupt or unsupported: {e}");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Reading a GGUF metadata value of type Array whose u64 length prefix exceeds 1,000,000 - corruption, wrong offset parsing, or a malformed KV entry.

Common situations: Corrupted model files, parsing desynchronization after an earlier malformed entry, adversarial/fuzzed files, buggy conversion tools writing wrong array lengths.

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/8c045b7251056d93. Report an issue: GitHub.

Appendix: source

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

        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()),
        GgufValueType::Uint32 => Ok(reader.read_u32::<LittleEndian>()?.to_string()),
        GgufValueType::Int32 => Ok(reader.read_i32::<LittleEndian>()?.to_string()),
        GgufValueType::Float32 => Ok(reader.read_f32::<LittleEndian>()?.to_string()),
        GgufValueType::Bool => Ok((reader.read_u8()? != 0).to_string()),
        GgufValueType::String => read_gguf_string(reader),
        GgufValueType::Uint64 => Ok(reader.read_u64::<LittleEndian>()?.to_string()),
        GgufValueType::Int64 => Ok(reader.read_i64::<LittleEndian>()?.to_string()),
        GgufValueType::Float64 => Ok(reader.read_f64::<LittleEndian>()?.to_string()),
        GgufValueType::Array => {
            let elem_type_u32 = reader.read_u32::<LittleEndian>()?;
            let elem_type = GgufValueType::try_from(elem_type_u32)?;
            let len = reader.read_u64::<LittleEndian>()?;

            if len > 1_000_000 {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidData,
                    format!("Array length {} is unreasonably large", len),
                ));
            }

            if len > 24 {
                skip_array_data(reader, elem_type, len)?;
                return Ok(format!(
                    "<Array of type {:?} with {} elements, data skipped>",
                    elem_type, len
                ));
            }

            let mut elems = Vec::with_capacity(len as usize);
            for _ in 0..len {
                elems.push(read_gguf_value(reader, elem_type)?);
            }
            Ok(format!("[{}]", elems.join(", ")))

View on GitHub (pinned to 7205d770c1)