Zackriya-Solutions/meetily · error
Invalid model file: magic number {:?} doesn't match GGUF/GGM
Error message
Invalid model file: magic number {:?} doesn't match GGUF/GGML What it means
validate_model_file reads the first 4 bytes and requires the magic 'GGUF' (or a legacy 'ggjt'/'ggla'/'ggml'). Any other bytes produce this error: the file at the model path is not a GGUF model - most commonly an HTML error page that was saved in place of the binary.
Source
Thrown at frontend/src-tauri/src/summary/summary_engine/model_manager.rs:788
}
/// Validate that a file is a valid GGUF model
async fn validate_gguf_file(&self, path: &PathBuf) -> Result<()> {
let mut file = fs::File::open(path).await?;
// Read first 4 bytes to check for GGUF magic number
use tokio::io::AsyncReadExt;
let mut magic = [0u8; 4];
file.read_exact(&mut magic).await?;
// GGUF magic number is "GGUF" (0x47475546)
if &magic == b"GGUF" {
Ok(())
} else if &magic == b"ggjt" || &magic == b"ggla" || &magic == b"ggml" {
// Older formats (GGML, GGJT)
Ok(())
} else {
Err(anyhow!(
"Invalid model file: magic number {:?} doesn't match GGUF/GGML",
magic
))
}
}
/// Cancel an ongoing download
pub async fn cancel_download(&self, model_name: &str) -> Result<()> {
log::info!("Cancelling download for model: {}", model_name);
// Set cancellation flag - download loop will detect this and handle cleanup
{
let mut cancel_flag = self.cancel_download_flag.write().await;
*cancel_flag = Some(model_name.to_string());
}
// Note: active_downloads cleanup is handled by the download loop when it detects
// the cancellation flag. This avoids double-removal race condition.View on GitHub (pinned to 0281737d87)
Solutions
- Delete the bad file via delete_model and re-download
- Check the URL actually returns the binary: curl -sL <url> | head -c 4 should print GGUF
- If installing manually, verify with xxd -l 4 <file> that it shows 47475546 ('GGUF') and name it exactly as model_def.gguf_file
- Clear proxy/CDN/auth interference (captive portals, authenticated mirrors) and retry
Defensive patterns
Strategy: validation
Validate before calling
// Cheap magic check before trusting any model file
fn is_gguf_file(path: &Path) -> bool {
use std::io::Read;
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" || &magic == b"ggml" || &magic == b"ggjt" || &magic == b"ggla")
} Type guard
fn is_valid_model_file(path: &Path) -> bool {
std::fs::metadata(path).map(|m| m.is_file()).unwrap_or(false) && is_gguf_file(path)
} Try / catch
try { manager.download_model(name).await? }
catch (e) if e.to_string().contains("magic number") {
// an HTML error page or wrong file was saved - delete and re-download from the canonical URL
manager.delete_model(name).await.ok();
manager.download_model(name).await?;
} Prevention
- Validate the magic bytes on any manually installed model before first run
- curl -sL <model url> | head -c 4 must print GGUF before relying on the URL
- Never rename non-GGUF files to .gguf; the loader checks content, not extension
When it happens
Trigger: Post-download validation or load reads a file whose header is not GGUF/GGML: a 404/redirect/auth-wall HTML page saved as the .gguf, a corrupted first block from a bad resume, or a user manually placing a non-GGUF file in the models/summary directory.
Common situations: HuggingFace/LFS redirect or CDN error page saved instead of the binary, captive portal intercepting the download, renaming a .bin or .onnx file to .gguf, partial-file resume where offsets shifted.
Related errors
- File validation failed: {}
- {}: {}
- Unknown model: {}
- Error writing to file: {}
- No transcript text available. Please add some text first.
AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16).
Data as JSON: /api/errors/a14a21f8602aa305.
Report an issue: GitHub.