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
- Re-download or re-export the model file; verify its SHA-256 against the publisher's checksum
- Verify the file starts with the GGUF magic and a plausible version (2 or 3) with a hex dump
- If the count is legitimately near the limit (large MoE models), raise MAX_TENSORS in helpers.rs and rebuild
- 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
- Verify downloaded model checksums before parsing
- Use llama.cpp's gguf_dump to validate files in CI before shipping them
- Reject files whose header tensor_count is implausible for their size
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
- tensor claims dimensions
- Array length is unreasonably large
- Error reading metadata entry
- Failed to read key for metadata entry
- Failed to read name for tensor
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)