huggingface/candle · error

gguf: metadata_kv_count {metadata_kv_count} exceeds max {GGU

Error message

gguf: metadata_kv_count {metadata_kv_count} exceeds max {GGUF_MAX_ARRAY_ELEMENTS}

What it means

Same guard as tensor_count but applied to the header's metadata_kv_count field. A declared metadata key/value count above GGUF_MAX_ARRAY_ELEMENTS would lead to unbounded allocation/loops, so candle bails before parsing the metadata.

Source

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

}

impl Content {
    pub fn read<R: std::io::Seek + std::io::Read>(reader: &mut R) -> Result<Self> {
        // Capture the file size once so the bounds checks below don't have to
        // seek to the end and back on every length-prefixed read.
        let start = reader.stream_position()?;
        let file_size = reader.seek(std::io::SeekFrom::End(0))?;
        reader.seek(std::io::SeekFrom::Start(start))?;

        let magic = VersionedMagic::read(reader)?;
        let tensor_count = read_length(reader, &magic)?;
        let metadata_kv_count = read_length(reader, &magic)?;

        if tensor_count > GGUF_MAX_ARRAY_ELEMENTS {
            crate::bail!("gguf: tensor_count {tensor_count} exceeds max {GGUF_MAX_ARRAY_ELEMENTS}")
        }
        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"

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Re-download the model file and verify its checksum/integrity
  2. Validate GGUF magic and header before handing to candle
  3. Update candle-core in case a newer release supports additional value types
  4. Do not open GGUF files from untrusted sources
Defensive patterns

Strategy: validation

Validate before calling

let meta = std::fs::metadata("model.gguf")?;
if meta.len() < 32 || &std::fs::read("model.gguf")?[..4] != *b"GGUF" {
    return Err(anyhow!("not a valid gguf file"));
}

Try / catch

match GgufFile::from_reader(&mut reader) {
    Ok(g) => g,
    Err(e) if e.to_string().contains("metadata_kv_count") => {
        eprintln!("corrupt gguf header; re-download the file");
        return Err(e.into());
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: GgufFile::read on a file whose header metadata_kv_count exceeds GGUF_MAX_ARRAY_ELEMENTS — corrupt, truncated, or malicious GGUF file.

Common situations: Downloading models over flaky connections without checksum verification; opening arbitrary untrusted .gguf files; mismatched file due to wrong path pointing to a non-GGUF binary.

Related errors


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