{"record":{"id":"0232f76b439f942e","repo":"janhq/jan","slug":"not-a-gguf-file","errorCode":null,"errorMessage":"Not a GGUF file","messagePattern":"Not a GGUF file","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/plugins/tauri-plugin-llamacpp/src/gguf/helpers.rs","lineNumber":96,"sourceCode":"        file.read_u64::<LittleEndian>()?; // offset into the data section\n\n        if wanted.contains(&name) && !found.contains(&name) {\n            found.push(name);\n            if found.len() == wanted.len() {\n                break;\n            }\n        }\n    }\n    Ok(found)\n}\n\n/// Header plus the whole KV section, leaving the reader positioned at the\n/// start of the tensor-info block.\nfn read_header<R: Read + Seek>(file: &mut BufReader<R>) -> io::Result<GgufMetadata> {\n    let mut magic = [0u8; 4];\n    file.read_exact(&mut magic)?;\n    if &magic != b\"GGUF\" {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            \"Not a GGUF file\",\n        ));\n    }\n\n    let version = file.read_u32::<LittleEndian>()?;\n    let tensor_count = file.read_u64::<LittleEndian>()?;\n    let metadata_count = file.read_u64::<LittleEndian>()?;\n\n    let mut metadata_map = std::collections::HashMap::new();\n    for i in 0..metadata_count {\n        match read_metadata_entry(file, i) {\n            Ok((key, value)) => {\n                metadata_map.insert(key, value);\n            }\n            Err(e) => {\n                return Err(io::Error::new(\n                    io::ErrorKind::InvalidData,","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/src-tauri/plugins/tauri-plugin-llamacpp/src/gguf/helpers.rs#L78-L114","documentation":"read_header validates the first 4 bytes of the stream against the GGUF magic b\"GGUF\" and fails with InvalidData if they differ. It is the parser's file-format gate: whatever was passed in is not a GGUF file at all.","triggerScenarios":"Calling read_gguf_metadata or find_gguf_tensors with a reader whose first 4 bytes are not 'GGUF' - e.g. a safetensors, .bin, .ggml, or text file passed by mistake.","commonSituations":"Wrong file extension or wrong model directory in config, pointing at a tokenizer/config JSON instead of weights, downloading an HTML error page saved as model.gguf, .ggml/.bin legacy models.","solutions":["Point the code at an actual .gguf weights file (check the path in your config)","Inspect the first 4 bytes with a hex dump or `head -c 4 model.gguf` to confirm the magic","If it's an HTML page, the download failed - re-download from the correct URL","Convert .ggml/.bin legacy models to GGUF v2/v3 before loading"],"exampleFix":"// before\nlet f = std::fs::File::open(\"models/tokenizer.json\")?;\nlet meta = read_gguf_metadata(f)?; // Not a GGUF file\n// after\nlet path = \"models/qwen2-7b-q4_k_m.gguf\";\nlet mut magic = [0u8; 4];\nstd::fs::File::open(path)?.read_exact(&mut magic)?;\nassert_eq!(&magic, b\"GGUF\", \"{} is not a GGUF file\", path);\nlet meta = read_gguf_metadata(std::fs::File::open(path)?)?;","handlingStrategy":"validation","validationCode":"fn is_gguf(path: &std::path::Path) -> io::Result<bool> {\n    use std::io::Read;\n    let mut magic = [0u8; 4];\n    std::fs::File::open(path)?.read_exact(&mut magic)?;\n    Ok(&magic == b\"GGUF\")\n}\n// call before read_gguf_metadata to give a friendly message","typeGuard":null,"tryCatchPattern":"match read_gguf_metadata(file) {\n    Err(e) if e.to_string() == \"Not a GGUF file\" => {\n        eprintln!(\"{} is not a GGUF model; check the path/extension\", path);\n    }\n    other => other?,\n}","preventionTips":["Check the magic bytes before parsing any model file","Keep model paths in config pointing at .gguf weights, not tokenizer/config JSONs","Detect HTML error pages saved as .gguf after failed downloads"],"tags":["gguf","file-format","magic-number","binary-parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"7205d770c1e097c3daf35a911176410e93bc5564","analyzedAt":"2026-09-17T14:27:30.100Z","contentChangedAt":"2026-09-17T14:27:30.100Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}