databendlabs/databend · error

Expected to have bytes

Error message

Expected to have bytes {:?}

What it means

CursorReadBytesExt::must_ignore_bytes consumes bs.len() bytes from the cursor if they exactly match bs. If the cursor does not hold those bytes (mismatch or EOF), it fails with an InvalidData io error that embeds the expected byte sequence for debugging.

Solutions

  1. Compare the error's {:?} bytes with the actual data at the cursor position to find the mismatch.
  2. Use ignore_bytes(bs) if the prefix is optional or may vary.
  3. Check the producer/writer emits the exact expected byte sequence (endianness, encoding).

Example fix

// before
cursor.must_ignore_bytes(b"MAGIC")?;

// after
if !cursor.ignore_bytes(b"MAGIC") {
    return Err(anyhow!("unexpected file header"));
}
Defensive patterns

Strategy: validation

Validate before calling

if remaining_bytes(cursor) < expected.len() || !starts_with(cursor, expected) {
    return Err(anyhow!("unexpected prefix"));
}

Try / catch

if !cursor.ignore_bytes(b"MAGIC") {
    return Err(anyhow!("not the expected file format"));
}

Prevention

When it happens

Trigger: Calling must_ignore_bytes(bs) when the upcoming bytes differ from bs or fewer than bs.len() bytes remain.

Common situations: Validating magic numbers, version tags, or fixed prefixes in binary formats when parsing misaligned, wrong-version, or truncated data.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/78fbf5f56a7000c3. Report an issue: GitHub.

Appendix: source

Thrown at src/common/io/src/cursor_ext/cursor_read_bytes_ext.rs:49

    fn until(&mut self, delim: u8, buf: &mut Vec<u8>) -> usize;
    fn keep_read(&mut self, buf: &mut Vec<u8>, f: impl Fn(u8) -> bool) -> usize;
    fn eof(&mut self) -> bool;
    fn must_eof(&mut self) -> Result<()>;
    fn must_ignore(&mut self, f: impl Fn(u8) -> bool) -> Result<()> {
        if !self.ignore(f) {
            return Err(std::io::Error::new(
                ErrorKind::InvalidData,
                "Expected to ignore a byte",
            ));
        }
        Ok(())
    }

    fn must_ignore_byte(&mut self, b: u8) -> Result<()>;

    fn must_ignore_bytes(&mut self, bs: &[u8]) -> Result<()> {
        if !self.ignore_bytes(bs) {
            return Err(std::io::Error::new(
                ErrorKind::InvalidData,
                format!("Expected to have bytes {:?}", bs),
            ));
        }
        Ok(())
    }

    fn must_ignore_insensitive_bytes(&mut self, bs: &[u8]) -> Result<()> {
        if !self.ignore_insensitive_bytes(bs) {
            return Err(std::io::Error::new(
                ErrorKind::InvalidData,
                format!("Expected to have insensitive bytes {:?}", bs),
            ));
        }
        Ok(())
    }
}

View on GitHub (pinned to 288d84d76e)