huggingface/candle · error
gguf: array of {len} elements needs at least {needed} bytes,
Error message
gguf: array of {len} elements needs at least {needed} bytes, only {remaining} remaining What it means
After reading an array's declared length, Value::read computes the minimum bytes the array must occupy on disk and compares that with the bytes remaining in the file; it bails when the array cannot possibly fit. This catches truncated files and bogus length fields early instead of failing mid-read or over-allocating. It is a size-consistency guard added as hardening.
Source
Thrown at candle-core/src/quantized/gguf_file.rs:356
ValueType::F32 => Self::F32(reader.read_f32::<LittleEndian>()?),
ValueType::F64 => Self::F64(reader.read_f64::<LittleEndian>()?),
ValueType::Bool => match reader.read_u8()? {
0 => Self::Bool(false),
1 => Self::Bool(true),
b => crate::bail!("unexpected bool value {b}"),
},
ValueType::String => Self::String(read_string(reader, magic, file_size)?),
ValueType::Array => {
let value_type = reader.read_u32::<LittleEndian>()?;
let value_type = ValueType::from_u32(value_type)?;
let len = read_length(reader, magic)?;
if len > GGUF_MAX_ARRAY_ELEMENTS {
crate::bail!("gguf: array length {len} exceeds max {GGUF_MAX_ARRAY_ELEMENTS}")
}
let needed = len.saturating_mul(value_type.min_disk_size(magic));
let remaining = remaining_bytes(reader, file_size)?;
if needed > remaining {
crate::bail!(
"gguf: array of {len} elements needs at least {needed} bytes, only {remaining} remaining"
)
}
let mut vs = Vec::new();
for _ in 0..len {
vs.push(Value::read(
reader,
value_type,
magic,
depth + 1,
file_size,
)?)
}
Self::Array(vs)
}
};
Ok(v)
}View on GitHub (pinned to d5fee525bf)
Solutions
- Re-download the file and compare byte size/checksum with the publisher's.
- Check the reported numbers in the message: len, needed bytes vs remaining bytes pinpoint how truncated the file is.
- Make sure the file finished copying/downloading before parsing (e.g. verify final size).
- If you produce GGUF files yourself, ensure lengths match the actual written elements.
Example fix
// before
let content = gguf_file::Content::read(&mut reader)?; // fails on partial file
// after
let expected_size: u64 = 4_618_022_272;
if std::fs::metadata(path)?.len() < expected_size {
bail!("GGUF download incomplete");
}
let content = gguf_file::Content::read(&mut reader)?; Defensive patterns
Strategy: validation
Validate before calling
// check completeness before parsing
let expected: u64 = /* publisher's byte size */;
let actual = std::fs::metadata(path)?.len();
if actual < expected { bail!("incomplete gguf: {} < {} bytes", actual, expected); } Try / catch
match gguf_file::Content::read(&mut reader) {
Ok(c) => c,
Err(e) if e.to_string().contains("only") && e.to_string().contains("remaining") => {
eprintln!("GGUF truncated: {e}; re-download the file");
return Err(Error::Msg("truncated gguf".into()));
}
Err(e) => return Err(e.into()),
} Prevention
- Download to a temp file and rename only after completion
- Compare final file size against the publisher's expected size
- Never parse a GGUF file while a copy/download is still in progress
- The error's len/needed/remaining numbers tell you how truncated the file is — log them
When it happens
Trigger: Reading a truncated/incomplete GGUF download whose header declares more array elements than the file has bytes for; a corrupted length field inflating len; a miscomputed min_disk_size mismatch when reading with older magic versions.
Common situations: Interrupted model downloads; partial uploads; storage corruption; reading a file while it is still being written/copied.
Related errors
- gguf: value nesting depth exceeds max {GGUF_MAX_VALUE_DEPTH}
- unexpected bool value {b}
- gguf: array length {len} exceeds max {GGUF_MAX_ARRAY_ELEMENT
- not a f32 {v:?}
- not a f64 {v:?}
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/4d41707d1a0b454e.
Report an issue: GitHub.