{"record":{"id":"63148b718fa620fd","repo":"huggingface/candle","slug":"gguf-array-length-len-exceeds-max-gguf-max-arr","errorCode":null,"errorMessage":"gguf: array length {len} exceeds max {GGUF_MAX_ARRAY_ELEMENTS}","messagePattern":"gguf: array length (.+?) exceeds max (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-core/src/quantized/gguf_file.rs","lineNumber":351,"sourceCode":"            ValueType::I16 => Self::I16(reader.read_i16::<LittleEndian>()?),\n            ValueType::U32 => Self::U32(reader.read_u32::<LittleEndian>()?),\n            ValueType::I32 => Self::I32(reader.read_i32::<LittleEndian>()?),\n            ValueType::U64 => Self::U64(reader.read_u64::<LittleEndian>()?),\n            ValueType::I64 => Self::I64(reader.read_i64::<LittleEndian>()?),\n            ValueType::F32 => Self::F32(reader.read_f32::<LittleEndian>()?),\n            ValueType::F64 => Self::F64(reader.read_f64::<LittleEndian>()?),\n            ValueType::Bool => match reader.read_u8()? {\n                0 => Self::Bool(false),\n                1 => Self::Bool(true),\n                b => crate::bail!(\"unexpected bool value {b}\"),\n            },\n            ValueType::String => Self::String(read_string(reader, magic, file_size)?),\n            ValueType::Array => {\n                let value_type = reader.read_u32::<LittleEndian>()?;\n                let value_type = ValueType::from_u32(value_type)?;\n                let len = read_length(reader, magic)?;\n                if len > GGUF_MAX_ARRAY_ELEMENTS {\n                    crate::bail!(\"gguf: array length {len} exceeds max {GGUF_MAX_ARRAY_ELEMENTS}\")\n                }\n                let needed = len.saturating_mul(value_type.min_disk_size(magic));\n                let remaining = remaining_bytes(reader, file_size)?;\n                if needed > remaining {\n                    crate::bail!(\n                        \"gguf: array of {len} elements needs at least {needed} bytes, only {remaining} remaining\"\n                    )\n                }\n                let mut vs = Vec::new();\n                for _ in 0..len {\n                    vs.push(Value::read(\n                        reader,\n                        value_type,\n                        magic,\n                        depth + 1,\n                        file_size,\n                    )?)\n                }","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-core/src/quantized/gguf_file.rs#L333-L369","documentation":"Value::read caps GGUF arrays at GGUF_MAX_ARRAY_ELEMENTS and throws this when the declared array length exceeds the cap. The length is read from the file header, so a huge declared length would otherwise cause enormous pre-allocation or DoS. This is a hardening guard against malformed or malicious files.","triggerScenarios":"Parsing a GGUF file whose metadata array header declares an element count above the library's maximum — seen with corrupted length bytes, adversarially crafted files, or files larger than the cap permits.","commonSituations":"Untrusted model downloads processed without validation; corrupted vocabulary arrays (tokenizer.ggml.tokens) where the u64 length field is garbage; fuzz-tested inputs.","solutions":["Treat the file as corrupt: verify its checksum and re-download from a trusted source.","Confirm the file opens correctly in a reference reader (llama.cpp's gguf tooling) to rule out parser mismatch.","Update candle — the cap is part of hardening fixes in recent versions.","If you genuinely need bigger arrays, patch the constant and rebuild candle (weigh the DoS tradeoff)."],"exampleFix":"// before\nlet content = gguf_file::Content::read(&mut reader)?;\n// after\nlet meta = std::fs::metadata(path)?;\nprintln!(\"file size {}\", meta.len()); // sanity-check before parsing\nlet content = gguf_file::Content::read(&mut reader)?;","handlingStrategy":"validation","validationCode":"// pre-screen: refuse implausibly huge metadata arrays relative to file size\nlet meta = std::fs::metadata(path)?;\nif meta.len() < 64 || meta.len() > MAX_ACCEPTED_GGUF_SIZE { bail!(\"gguf size out of range\"); }","typeGuard":null,"tryCatchPattern":"match gguf_file::Content::read(&mut reader) {\n    Ok(c) => c,\n    Err(e) if e.to_string().contains(\"exceeds max\") => {\n        eprintln!(\"GGUF declares an oversized array — likely corrupt or hostile\");\n        return Err(Error::Msg(\"invalid gguf array length\".into()));\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Never parse untrusted GGUF files without validation; the cap is a DoS guard","Verify checksums from the model publisher","Keep candle updated so the GGUF_MAX_ARRAY_ELEMENTS guard is present","Pre-screen with an independent GGUF inspector for files from unknown sources"],"tags":["candle","gguf","corrupt-file","security","dos-protection"],"backgroundTag":"malformed-file-data","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}