BoundaryML/baml · error · io::Error

blob size mismatch for {}; expected {} bytes, got {} bytes

Error message

blob size mismatch for {}; expected {} bytes, got {} bytes

What it means

BlobStore::verify_bytes compares the length of the bytes read from disk against the size_bytes recorded in the BlobRef and fails when they differ. This guarantees content-addressed blobs are read back at exactly their recorded size before the digest check runs. It surfaces to callers as an io::Error with InvalidData kind from read_blob.

Source

Thrown at baml_language/crates/bex_events/src/value/artifact.rs:70

            ));
        }
        if !self.digest.bytes().all(|byte| byte.is_ascii_hexdigit()) {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                "invalid sha256 blob digest; expected only hex characters",
            ));
        }
        Ok(())
    }

    fn normalized_digest(&self) -> io::Result<String> {
        self.validate()?;
        Ok(self.digest.to_ascii_lowercase())
    }

    fn verify_bytes(&self, bytes: &[u8]) -> io::Result<()> {
        if bytes.len() != self.size_bytes {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    "blob size mismatch for {}; expected {} bytes, got {} bytes",
                    self.digest,
                    self.size_bytes,
                    bytes.len()
                ),
            ));
        }
        let actual = Self::sha256(bytes);
        if actual.digest != self.digest.to_ascii_lowercase() {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    "blob digest mismatch for {}; computed {}",
                    self.digest, actual.digest
                ),
            ));

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Delete the corrupt blob file and re-write it from the original bytes with write_blob(), which recomputes size and digest.
  2. Recompute the source content's SHA-256 and fix the BlobRef's size_bytes/digest if the reference itself is stale.
  3. Restore the blob store from backup or re-run the pipeline that produced the artifact.

Example fix

// before
let data = fs::read(&path)?; // truncated file, stale BlobRef
let blob = store.read_blob(&blob_ref)?;
// after
if !path.exists() || fs::metadata(&path)?.len() != blob_ref.size_bytes {
    store.write_blob(&blob_ref_from_bytes(original_bytes))?; // re-ingest
}
let blob = store.read_blob(&blob_ref)?;
Defensive patterns

Strategy: try-catch

Validate before calling

let meta = fs::metadata(&path)?;
if meta.len() != blob_ref.size_bytes {
    // size already mismatched; re-ingest blob before calling read_blob
}

Try / catch

match store.read_blob(&blob_ref) {
    Ok(bytes) => bytes,
    Err(e) if e.kind() == io::ErrorKind::InvalidData => {
        // corrupt/truncated blob: delete and rewrite from source
        let _ = fs::remove_file(store.path_for(&blob_ref)?);
        store.write_blob(&BlobRef::sha256(&original_bytes))?;
        store.read_blob(&BlobRef::sha256(&original_bytes))?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: read_blob() on a blob file that was truncated, partially written, appended to, or whose BlobRef metadata (size_bytes) points at a different blob version.

Common situations: Disk-full or crash during a previous write, manual tampering or editing of files under the blob store root, copying blob files between stores with stale BlobRef metadata, or a run interrupted mid-write leaving a partial .tmp that was promoted incorrectly.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/ec031bb3610a9234. Report an issue: GitHub.