janhq/jan · error · io::Error
Not a GGUF file
Error message
Not a GGUF file
What it means
Thrown by `read_gguf_metadata` after reading the first 4 bytes of the file and comparing them against the ASCII bytes `b"GGUF"`. The GGUF format always starts with this 4-byte magic header (offset 0). If the comparison fails, the file is not a valid GGUF container, so the parser aborts before reading version/tensor/metadata counts. It is returned as `io::Error` with kind `InvalidData`.
Source
Thrown at src-tauri/plugins/tauri-plugin-llamacpp/src/gguf/helpers.rs:13
use byteorder::{LittleEndian, ReadBytesExt};
use std::convert::TryFrom;
use std::io::{self, BufReader, Read, Seek};
use super::types::{GgufMetadata, GgufValueType};
pub fn read_gguf_metadata<R: Read + Seek>(reader: R) -> io::Result<GgufMetadata> {
let mut file = BufReader::new(reader);
let mut magic = [0u8; 4];
file.read_exact(&mut magic)?;
if &magic != b"GGUF" {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"Not a GGUF file",
));
}
let version = file.read_u32::<LittleEndian>()?;
let tensor_count = file.read_u64::<LittleEndian>()?;
let metadata_count = file.read_u64::<LittleEndian>()?;
let mut metadata_map = std::collections::HashMap::new();
for i in 0..metadata_count {
match read_metadata_entry(&mut file, i) {
Ok((key, value)) => {
metadata_map.insert(key, value);
}
Err(e) => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,View on GitHub (pinned to fad3f12a14)
Solutions
- Verify the file is actually GGUF: run `head -c 4 file.gguf | xxd` and confirm it prints `47 47 55 46` (`GGUF`).
- Re-download the model from a trusted source if the magic bytes do not match; a corrupted or HTML-error-page download is the usual cause.
- Confirm the path handed to `read_gguf_metadata` is the model file and not a directory, symlink target, or unrelated artifact.
- If you must support legacy GGML, parse it with a separate GGML reader rather than the GGUF parser.
Example fix
// before
let meta = read_gguf_metadata(File::open(path)?)?;
// after
let mut f = File::open(path)?;
let mut magic = [0u8; 4];
f.read_exact(&mut magic)?;
if &magic != b"GGUF" {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("{} is not a GGUF file (magic={:?})", path.display(), magic),
));
}
f.seek(SeekFrom::Start(0))?;
let meta = read_gguf_metadata(f)?; Defensive patterns
Strategy: validation
Validate before calling
fn is_gguf(path: &Path) -> bool {
let mut f = match std::fs::File::open(path) {
Ok(f) => f,
Err(_) => return false,
};
let mut magic = [0u8; 4];
f.read_exact(&mut magic).is_ok() && &magic == b"GGUF"
}
// before calling read_gguf_metadata:
if !is_gguf(&path) {
return Err(format!("{} is not a GGUF file", path.display()));
} Type guard
null
Try / catch
match read_gguf_metadata(File::open(&path)?) {
Ok(meta) => Ok(meta),
Err(e) if e.kind() == io::ErrorKind::InvalidData && e.to_string().contains("Not a GGUF") => {
Err(UserError::InvalidModelFile(path.display().to_string()))
}
Err(e) => Err(e.into()),
} Prevention
- Validate the magic bytes before handing the file to the full parser.
- Compute and compare the file's checksum against the published value before parsing.
- Restrict the file picker to .gguf extensions in the UI.
When it happens
Trigger: Calling `read_gguf_metadata(reader)` with any non-GGUF input: a GGML (legacy) file, a safetensors/ckpt/bin file, a partially-downloaded GGUF whose header is truncated to fewer than 4 bytes, or an empty file (read_exact then returns UnexpectedEof before the comparison is reached). Passing a file opened on a path that resolved to a directory or a text file produces the same outcome.
Common situations: Downloading a model from a URL that returned an HTML error page, mistaking a GGML v1 file for GGUF, pointing the loader at a `.bin` LLaMA checkpoint, or a truncated download where the magic check coincidentally still fails because the bytes are HTML/JSON. Also seen when the file handle is a different file than expected (path race, wrong symlink).
Related errors
- String length {} is unreasonably large
- <Utf8Error>
- Array length {} is unreasonably large
- Unknown GGUF value type: {}
- Error reading metadata entry {}: {}
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/0232f76b439f942e.
Report an issue: GitHub.