{"record":{"id":"c8b8c3819fc3219f","repo":"huggingface/candle","slug":"gguf-header-declares-tensor-count-tensors-and","errorCode":null,"errorMessage":"gguf: header declares {tensor_count} tensors and {metadata_kv_count} metadata entries, needs at least {needed} bytes, only {remaining} remaining","messagePattern":"gguf: header declares (.+?) tensors and (.+?) metadata entries, needs at least (.+?) bytes, only (.+?) remaining","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-core/src/quantized/gguf_file.rs","lineNumber":501,"sourceCode":"        if metadata_kv_count > GGUF_MAX_ARRAY_ELEMENTS {\n            crate::bail!(\n                \"gguf: metadata_kv_count {metadata_kv_count} exceeds max {GGUF_MAX_ARRAY_ELEMENTS}\"\n            )\n        }\n\n        // Reject header-declared counts that can't fit in the file at minimum size.\n        // Per-entry minima: a metadata kv is at least `key_len_prefix + u32 value_type\n        // + 1 byte value`; a tensor info is at least `name_len_prefix + u32 n_dims\n        // + u32 dtype + u64 offset`.\n        let prefix = magic.length_prefix_size();\n        let min_per_kv = prefix + 4 + 1;\n        let min_per_tensor = prefix + 4 + 4 + 8;\n        let needed = metadata_kv_count\n            .saturating_mul(min_per_kv)\n            .saturating_add(tensor_count.saturating_mul(min_per_tensor));\n        let remaining = remaining_bytes(reader, file_size)?;\n        if needed > remaining {\n            crate::bail!(\n                \"gguf: header declares {tensor_count} tensors and {metadata_kv_count} metadata entries, needs at least {needed} bytes, only {remaining} remaining\"\n            )\n        }\n\n        let mut metadata = HashMap::new();\n        for _idx in 0..metadata_kv_count {\n            let key = read_string(reader, &magic, file_size)?;\n            let value_type = reader.read_u32::<LittleEndian>()?;\n            let value_type = ValueType::from_u32(value_type)?;\n            let value = Value::read(reader, value_type, &magic, 0, file_size)?;\n            metadata.insert(key, value);\n        }\n        let mut tensor_infos = HashMap::new();\n        for _idx in 0..tensor_count {\n            let tensor_name = read_string(reader, &magic, file_size)?;\n            let n_dimensions = reader.read_u32::<LittleEndian>()?;\n            if n_dimensions > GGUF_MAX_TENSOR_DIMS {\n                crate::bail!(","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-core/src/quantized/gguf_file.rs#L483-L519","documentation":"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.","triggerScenarios":"GgufFile::read where tensor_count * min_tensor_size + metadata_kv_count * min_kv_size > remaining file bytes — a truncated or fabricated GGUF file.","commonSituations":"Interrupted downloads; cloud sync placeholders not fully fetched; sparse/corrupt files; deliberately crafted files with inflated header counts.","solutions":["Re-download the GGUF file completely and compare file size/checksum against the published value","Check that the download tool finished (no partial .part files)","Verify storage is not returning placeholder/sparse data (e.g. OneDrive/Dropbox on-demand files)"],"exampleFix":"// before\nlet gguf = GgufFile::from_reader(&mut BufReader::new(File::open(\"model.gguf\")?))?;\n// after\nlet meta = std::fs::metadata(\"model.gguf\")?;\nif meta.len() < EXPECTED_MIN_SIZE {\n    return Err(anyhow!(\"model.gguf is truncated: {} bytes, expected at least {}\", meta.len(), EXPECTED_MIN_SIZE));\n}\nlet gguf = GgufFile::from_reader(&mut BufReader::new(File::open(\"model.gguf\")?))?;","handlingStrategy":"validation","validationCode":"let meta = std::fs::metadata(\"model.gguf\")?;\nif meta.len() < EXPECTED_FILE_SIZE {\n    return Err(anyhow!(\"truncated: {} < {} bytes\", meta.len(), EXPECTED_FILE_SIZE));\n}","typeGuard":null,"tryCatchPattern":"match GgufFile::from_reader(&mut reader) {\n    Ok(g) => g,\n    Err(e) if e.to_string().contains(\"needs at least\") => {\n        eprintln!(\"gguf file is truncated relative to its header; re-download\");\n        return Err(e.into());\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Compare downloaded file size to the published size before loading","Disable on-demand/cloud placeholder file modes for model directories","Re-download interrupted transfers"],"tags":["gguf","truncated-file","file-format"],"backgroundTag":"gguf-header-count-exceeds-limit","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}