janhq/jan · error · io::Error

tensor count is unreasonably large

Error message

tensor count {} is unreasonably large

What it means

find_gguf_tensors refuses to walk the tensor-info block when the header declares more than MAX_TENSORS (1,000,000) tensors. The bound exists so a corrupt or malicious header cannot drive an effectively unbounded loop. It almost always indicates a corrupted, truncated, or non-GGUF-mislabeled file rather than a genuinely huge model.

Solutions

  1. Re-download or re-export the model file; verify its SHA-256 against the publisher's checksum
  2. Verify the file starts with the GGUF magic and a plausible version (2 or 3) with a hex dump
  3. If the count is legitimately near the limit (large MoE models), raise MAX_TENSORS in helpers.rs and rebuild
  4. Test the file with llama.cpp's gguf_dump or similar tool to confirm header integrity

Example fix

// before
let bytes = std::fs::read("model.gguf").unwrap();
let found = find_gguf_tensors(Cursor::new(bytes), &wanted)?;
// after
let bytes = std::fs::read("model.gguf")?;
assert_eq!(sha256(&bytes), expected_digest, "model file corrupt - re-download");
let found = find_gguf_tensors(Cursor::new(bytes), &wanted)?;
Defensive patterns

Strategy: validation

Validate before calling

fn header_tensor_count_ok(bytes: &[u8]) -> bool {
    if bytes.len() < 16 || &bytes[0..4] != b"GGUF" { return false; }
    let count = u64::from_le_bytes(bytes[8..16].try_into().unwrap());
    count <= 1_000_000
}
// call header_tensor_count_ok(&bytes) before find_gguf_tensors

Prevention

When it happens

Trigger: Calling find_gguf_tensors on a file whose u64 tensor_count field (bytes 8-16 of the header) exceeds 1,000,000 - typically because the file is corrupted, partially downloaded, or not actually GGUF data.

Common situations: Interrupted model downloads, files whose first bytes happen to be 'GGUF' but whose header is garbage, quantization/conversion tools writing bad headers, feeding random binary data to the parser.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

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

    reader: R,
    wanted: &[String],
) -> io::Result<Vec<String>> {
    let mut file = BufReader::new(reader);
    let meta = read_header(&mut file)?;

    if wanted.is_empty() {
        return Ok(Vec::new());
    }
    // v1 sized strings and dimensions with u32s. llama.cpp refuses that
    // version outright, and reading it as v2 would invent names.
    if meta.version < 2 {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!("GGUF version {} has no readable tensor block", meta.version),
        ));
    }
    if meta.tensor_count > MAX_TENSORS {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!("tensor count {} is unreasonably large", meta.tensor_count),
        ));
    }

    let mut found: Vec<String> = Vec::new();
    for i in 0..meta.tensor_count {
        let name = read_gguf_string(&mut file).map_err(|e| {
            io::Error::new(
                io::ErrorKind::InvalidData,
                format!("Failed to read name for tensor {}: {}", i, e),
            )
        })?;
        let n_dims = file.read_u32::<LittleEndian>()?;
        if n_dims > MAX_TENSOR_DIMS {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!("tensor {} claims {} dimensions", i, n_dims),

View on GitHub (pinned to 7205d770c1)