janhq/jan · error · io::Error

Failed to read key for metadata entry

Error message

Failed to read key for metadata entry {}: {}

What it means

read_metadata_entry could not read the length-prefixed key string for metadata entry `index`. read_gguf_string's failure (oversized length > 1 MiB, truncated data, or invalid UTF-8) is re-tagged with the entry index for diagnosis.

Solutions

  1. Re-download the model file and verify its checksum
  2. Check the file with llama.cpp's gguf_dump to find where the KV section breaks
  3. Verify the file size matches the publisher's expected size (truncation check)
  4. If converting yourself, re-run the conversion with a current llama.cpp/gguf tool version

Example fix

// before
let meta = read_gguf_metadata(File::open("model.gguf")?)?;
// after
let bytes = std::fs::read("model.gguf")?;
if bytes.len() != EXPECTED_SIZE {
    anyhow::bail!("download incomplete: {} of {} bytes", bytes.len(), EXPECTED_SIZE);
}
let meta = read_gguf_metadata(Cursor::new(bytes))?;
Defensive patterns

Strategy: validation

Validate before calling

fn plausible_gguf_size(path: &std::path::Path, expected: u64) -> io::Result<bool> {
    Ok(std::fs::metadata(path)?.len() == expected)
}
// truncated files produce garbage length prefixes

Prevention

When it happens

Trigger: Calling read_gguf_metadata / find_gguf_tensors on a file where entry `index`'s u64 key-length prefix is garbage (points past EOF or exceeds 1 MiB) or the key bytes are truncated.

Common situations: Corrupted or partially downloaded GGUF files, desynchronized parsing after an earlier bad record, files produced by buggy converters writing wrong length prefixes.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17). Data as JSON: /api/errors/0dcb3cee71b8ed32. Report an issue: GitHub.

Appendix: source

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

                    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)> {
    let key = read_gguf_string(reader).map_err(|e| {
        io::Error::new(
            io::ErrorKind::InvalidData,
            format!("Failed to read key for metadata entry {}: {}", index, e),
        )
    })?;

    let value_type_u32 = reader.read_u32::<LittleEndian>()?;
    let value_type = GgufValueType::try_from(value_type_u32)?;
    let value = read_gguf_value(reader, value_type)?;

    Ok((key, value))
}

fn read_gguf_string<R: Read + ReadBytesExt>(reader: &mut R) -> io::Result<String> {
    let len = reader.read_u64::<LittleEndian>()?;
    if len > (1024 * 1024) {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!("String length {} is unreasonably large", len),

View on GitHub (pinned to 7205d770c1)