huggingface/candle · error

unexpected bool value {b}

Error message

unexpected bool value {b}

What it means

GGUF encodes booleans as a single byte that must be exactly 0 or 1; Value::read throws this when the byte is anything else. The parser refuses to coerce other byte values (e.g. 2, 0xFF) to a bool. This indicates a corrupted, truncated, or non-conforming file since a valid GGUF writer never emits other bytes.

Source

Thrown at candle-core/src/quantized/gguf_file.rs:343

    ) -> Result<Self> {
        if depth > GGUF_MAX_VALUE_DEPTH {
            crate::bail!("gguf: value nesting depth exceeds max {GGUF_MAX_VALUE_DEPTH}")
        }
        let v = match value_type {
            ValueType::U8 => Self::U8(reader.read_u8()?),
            ValueType::I8 => Self::I8(reader.read_i8()?),
            ValueType::U16 => Self::U16(reader.read_u16::<LittleEndian>()?),
            ValueType::I16 => Self::I16(reader.read_i16::<LittleEndian>()?),
            ValueType::U32 => Self::U32(reader.read_u32::<LittleEndian>()?),
            ValueType::I32 => Self::I32(reader.read_i32::<LittleEndian>()?),
            ValueType::U64 => Self::U64(reader.read_u64::<LittleEndian>()?),
            ValueType::I64 => Self::I64(reader.read_i64::<LittleEndian>()?),
            ValueType::F32 => Self::F32(reader.read_f32::<LittleEndian>()?),
            ValueType::F64 => Self::F64(reader.read_f64::<LittleEndian>()?),
            ValueType::Bool => match reader.read_u8()? {
                0 => Self::Bool(false),
                1 => Self::Bool(true),
                b => crate::bail!("unexpected bool value {b}"),
            },
            ValueType::String => Self::String(read_string(reader, magic, file_size)?),
            ValueType::Array => {
                let value_type = reader.read_u32::<LittleEndian>()?;
                let value_type = ValueType::from_u32(value_type)?;
                let len = read_length(reader, magic)?;
                if len > GGUF_MAX_ARRAY_ELEMENTS {
                    crate::bail!("gguf: array length {len} exceeds max {GGUF_MAX_ARRAY_ELEMENTS}")
                }
                let needed = len.saturating_mul(value_type.min_disk_size(magic));
                let remaining = remaining_bytes(reader, file_size)?;
                if needed > remaining {
                    crate::bail!(
                        "gguf: array of {len} elements needs at least {needed} bytes, only {remaining} remaining"
                    )
                }
                let mut vs = Vec::new();
                for _ in 0..len {

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Re-download or re-export the GGUF file — the bytes do not conform to the GGUF spec.
  2. Check file size/integrity (checksum) before parsing.
  3. If your own writer produced it, emit exactly 0x00 or 0x01 for ValueType::Bool.
  4. If reading from a non-seekable stream, ensure no earlier read misaligned the position.

Example fix

// before
let flag = content.metadata.get("my.flag"); // parse already failed upstream
// after (writer side)
// before
w.write_u32::<LittleEndian>(flag as u32)?;
// after
w.write_u8(if flag { 1 } else { 0 })?;
Defensive patterns

Strategy: validation

Validate before calling

// verify integrity before parse
let digest = sha256_hex(File::open(path)?)?;
if digest != EXPECTED_SHA256 { bail!("GGUF file corrupt: bool byte invalid"); }

Try / catch

match gguf_file::Content::read(&mut reader) {
    Ok(c) => c,
    Err(e) if e.to_string().contains("unexpected bool value") => {
        eprintln!("corrupt GGUF (non-0/1 bool byte), re-download");
        return Err(Error::Msg("corrupt gguf".into()));
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Reading a GGUF file where a Bool-typed metadata value contains a byte other than 0 or 1 — caused by file corruption, a broken writer, or a desynchronized read stream after earlier parse errors.

Common situations: Partial downloads or truncated model files; custom/older GGUF writers encoding bools differently (e.g. as u32); reading a stream positioned at the wrong offset after a previous field was mis-parsed.

Related errors


AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02). Data as JSON: /api/errors/0328e44f2ddd40a9. Report an issue: GitHub.