quickwit-oss/tantivy · warning · io::Error

Unsupported

Unsupported

Error message

Async read is not supported.

What it means

FileSlice's default read_bytes_async trait method is a stub that always returns io::Error(Unsupported, "Async read is not supported."). Only backends that explicitly override read_bytes_async support async reads; the default (blocking, e.g. mmap-backed) implementation does not. This is a capability signal, not corruption.

Source

Thrown at common/src/file_slice.rs:30

/// Objects that represents files sections in tantivy.
///
/// By contract, whatever happens to the directory file, as long as a FileHandle
/// is alive, the data associated with it cannot be altered or destroyed.
///
/// The underlying behavior is therefore specific to the `Directory` that
/// created it. Despite its name, a [`FileSlice`] may or may not directly map to an actual file
/// on the filesystem.

#[async_trait]
pub trait FileHandle: 'static + Send + Sync + HasLen + fmt::Debug {
    /// Reads a slice of bytes.
    ///
    /// This method may panic if the range requested is invalid.
    fn read_bytes(&self, range: Range<usize>) -> io::Result<OwnedBytes>;

    #[doc(hidden)]
    async fn read_bytes_async(&self, _byte_range: Range<usize>) -> io::Result<OwnedBytes> {
        Err(io::Error::new(
            io::ErrorKind::Unsupported,
            "Async read is not supported.",
        ))
    }
}

#[derive(Debug)]
/// A File with it's length included.
pub struct WrapFile {
    file: File,
    len: usize,
}
impl WrapFile {
    /// Creates a new WrapFile and stores its length.
    pub fn new(file: File) -> io::Result<Self> {
        let len = file.metadata()?.len() as usize;
        Ok(WrapFile { file, len })
    }

View on GitHub (pinned to b5d8deb80c)

Solutions

  1. Use a FileSlice implementation that overrides read_bytes_async (e.g. an async-fs-backed wrapper)
  2. Fall back to the blocking read_bytes when Unsupported is returned
  3. Open the slice synchronously and wrap it in an in-memory OwnedBytes for async contexts
  4. Implement read_bytes_async in your custom FileSlice impl

Example fix

// before
let bytes = file_slice.read_bytes_async(range).await?;
// after
let bytes = match file_slice.read_bytes_async(range).await {
    Err(e) if e.kind() == io::ErrorKind::Unsupported => file_slice.read_bytes(range)?,
    other => other?,
};
Defensive patterns

Strategy: fallback

Try / catch

let bytes = match slice.read_bytes_async(range).await {
    Ok(b) => Ok(b),
    Err(e) if e.kind() == io::ErrorKind::Unsupported =>
        tokio::task::block_in_place(|| slice.read_bytes(range)),
    Err(e) => Err(e),
}?;

Prevention

When it happens

Trigger: Awaiting read_bytes_async (e.g. via async search/segment open paths) on a FileSlice implementation that didn't override the async method — typically a std::fs or mmap-backed slice, or a custom impl using the default method.

Common situations: Using async index-opening APIs on files opened with blocking File/mmap; mixing sync FileSlice with async executors; custom FileSlice impls that only implemented the sync read_bytes.

Related errors


AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05). Data as JSON: /api/errors/8df771be2ca1e52a. Report an issue: GitHub.