huggingface/candle · error

gguf: header declares {tensor_count} tensors and {metadata_k

Error message

gguf: header declares {tensor_count} tensors and {metadata_kv_count} metadata entries, needs at least {needed} bytes, only {remaining} remaining

What it means

candle cross-checks the header-declared counts against the actual remaining file size. Each tensor and metadata entry has a minimum byte size, and if the declared minimum total exceeds the bytes left in the file, the file cannot possibly be valid, so it is rejected before any allocation.

Source

Thrown at candle-core/src/quantized/gguf_file.rs:501

        if metadata_kv_count > GGUF_MAX_ARRAY_ELEMENTS {
            crate::bail!(
                "gguf: metadata_kv_count {metadata_kv_count} exceeds max {GGUF_MAX_ARRAY_ELEMENTS}"
            )
        }

        // Reject header-declared counts that can't fit in the file at minimum size.
        // Per-entry minima: a metadata kv is at least `key_len_prefix + u32 value_type
        // + 1 byte value`; a tensor info is at least `name_len_prefix + u32 n_dims
        // + u32 dtype + u64 offset`.
        let prefix = magic.length_prefix_size();
        let min_per_kv = prefix + 4 + 1;
        let min_per_tensor = prefix + 4 + 4 + 8;
        let needed = metadata_kv_count
            .saturating_mul(min_per_kv)
            .saturating_add(tensor_count.saturating_mul(min_per_tensor));
        let remaining = remaining_bytes(reader, file_size)?;
        if needed > remaining {
            crate::bail!(
                "gguf: header declares {tensor_count} tensors and {metadata_kv_count} metadata entries, needs at least {needed} bytes, only {remaining} remaining"
            )
        }

        let mut metadata = HashMap::new();
        for _idx in 0..metadata_kv_count {
            let key = read_string(reader, &magic, file_size)?;
            let value_type = reader.read_u32::<LittleEndian>()?;
            let value_type = ValueType::from_u32(value_type)?;
            let value = Value::read(reader, value_type, &magic, 0, file_size)?;
            metadata.insert(key, value);
        }
        let mut tensor_infos = HashMap::new();
        for _idx in 0..tensor_count {
            let tensor_name = read_string(reader, &magic, file_size)?;
            let n_dimensions = reader.read_u32::<LittleEndian>()?;
            if n_dimensions > GGUF_MAX_TENSOR_DIMS {
                crate::bail!(

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Re-download the GGUF file completely and compare file size/checksum against the published value
  2. Check that the download tool finished (no partial .part files)
  3. Verify storage is not returning placeholder/sparse data (e.g. OneDrive/Dropbox on-demand files)

Example fix

// before
let gguf = GgufFile::from_reader(&mut BufReader::new(File::open("model.gguf")?))?;
// after
let meta = std::fs::metadata("model.gguf")?;
if meta.len() < EXPECTED_MIN_SIZE {
    return Err(anyhow!("model.gguf is truncated: {} bytes, expected at least {}", meta.len(), EXPECTED_MIN_SIZE));
}
let gguf = GgufFile::from_reader(&mut BufReader::new(File::open("model.gguf")?))?;
Defensive patterns

Strategy: validation

Validate before calling

let meta = std::fs::metadata("model.gguf")?;
if meta.len() < EXPECTED_FILE_SIZE {
    return Err(anyhow!("truncated: {} < {} bytes", meta.len(), EXPECTED_FILE_SIZE));
}

Try / catch

match GgufFile::from_reader(&mut reader) {
    Ok(g) => g,
    Err(e) if e.to_string().contains("needs at least") => {
        eprintln!("gguf file is truncated relative to its header; re-download");
        return Err(e.into());
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: GgufFile::read where tensor_count * min_tensor_size + metadata_kv_count * min_kv_size > remaining file bytes — a truncated or fabricated GGUF file.

Common situations: Interrupted downloads; cloud sync placeholders not fully fetched; sparse/corrupt files; deliberately crafted files with inflated header counts.

Related errors


AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02). Data as JSON: /api/errors/c8b8c3819fc3219f. Report an issue: GitHub.