janhq/jan · error · io::Error

Error reading metadata entry {}: {}

Error message

Error reading metadata entry {}: {}

What it means

Wraps any error produced while reading the i-th metadata key/value pair inside the metadata loop. The function iterates `metadata_count` entries and, on failure of `read_metadata_entry`, re-wraps the underlying error as `InvalidData` with the entry index for diagnostics. It is a generic aggregator — the root cause lives one level deeper (key read, value-type decode, or value read).

Source

Thrown at src-tauri/plugins/tauri-plugin-llamacpp/src/gguf/helpers.rs:30

    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,
                    format!("Error reading metadata entry {}: {}", i, e),
                ));
            }
        }
    }

    Ok(GgufMetadata {
        version,
        tensor_count,
        metadata: metadata_map,
    })
}

fn read_metadata_entry<R: Read + Seek + ReadBytesExt>(
    reader: &mut R,
    index: u64,
) -> io::Result<(String, String)> {

View on GitHub (pinned to fad3f12a14)

Solutions

  1. Read the inner error message — it names the specific cause (key read, value type, value read); address that first.
  2. Verify file integrity with `sha256sum` against the published checksum to rule out truncation/corruption.
  3. If the index is small and consistent across files of the same model family, suspect a value-type or layout mismatch in `read_gguf_value`; otherwise suspect file corruption.
  4. Re-download the model from a trusted source if checksum mismatch indicates corruption.

Example fix

// before
match read_metadata_entry(&mut file, i) {
    Ok((k, v)) => { metadata_map.insert(k, v); }
    Err(e) => return Err(io::Error::new(InvalidData, format!("Error reading metadata entry {}: {}", i, e))),
}

// after - surface inner kind + byte offset for diagnostics
match read_metadata_entry(&mut file, i) {
    Ok((k, v)) => { metadata_map.insert(k, v); }
    Err(e) => {
        let pos = file.stream_position().unwrap_or(0);
        return Err(io::Error::new(InvalidData,
            format!("metadata entry {} failed at byte {}: {}", i, pos, e)));
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

match read_gguf_metadata(reader) {
    Ok(m) => Ok(m),
    Err(e) if e.to_string().contains("Error reading metadata entry") => {
        tracing::error!("GGUF metadata truncated/corrupt: {e}");
        Err(InvalidModel(e.to_string()))
    }
    Err(e) => Err(e.into()),
}

Prevention

When it happens

Trigger: Any structural corruption of the metadata kv-array: a truncated file cutting off mid-entry, a bad string length inside an entry, an unknown value-type discriminator, or an oversized array inside a metadata value. Also fires when `metadata_count` itself was misread (e.g. a 32-bit vs 64-bit length mismatch) so the loop walks past real data into garbage.

Common situations: Truncated GGUF download that parses the header fine but ends before all metadata entries are present; an editor or transport that mangled binary bytes; a non-standard quantized file whose metadata layout differs from what this parser expects. The index reported tells you how many entries parsed cleanly before failure.

Related errors


AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12). Data as JSON: /api/errors/240dadb2d46d601f. Report an issue: GitHub.