Skip to content

Large query causes broken pipe error #1400

Open
@pohlarized

Description

@pohlarized

Versions/Environment

  1. What version of Rust are you using? 1.85.0
  2. What operating system are you using? Arch Linux
  3. What versions of the driver and its dependencies are you using? (Run cargo pkgid mongodb & cargo pkgid bson) registry+https://github.com/rust-lang/crates.io-index#[email protected] & registry+https://github.com/rust-lang/crates.io-index#[email protected]
  4. What version of MongoDB are you using? (Check with the MongoDB shell using db.version()) 8.0
  5. What is your MongoDB topology (standalone, replica set, sharded cluster, serverless)? mongo:8.0 docker image self-hosted

Describe the bug

When issuing a large query, for example a big filter in a find operation, the mongodb driver generates an OS Error 32 "Broken Pipe".

The following example, where i create a filter with 1 700 000 random 16 character strings and then execute a find operation using that filter, causes the described error on my local machine.
You just need a mongoDB to connect to, but the query never even reaches the DB.
The same behaviour was seen on our server.

// main.rs
use mongodb::{
    Client,
    bson::{Document, doc},
};
use rand::distr::{Alphanumeric, SampleString};

#[tokio::main]
async fn main() {
    let client = Client::with_uri_str("mongodb://localhost:27017")
        .await
        .unwrap();
    let collection = client
        .database("database")
        .collection::<Document>("collection");

    let mut rng = rand::rng();
    let big_vec: Vec<String> = (0..1_700_000)
        .map(|_| Alphanumeric.sample_string(&mut rng, 16))
        .collect();
    let filter = doc! {
        "some_field": {
            "$in": big_vec
        }
    };

    match collection.find(filter).await {
        Ok(_cursor) => println!("Got cursor!"),
        Err(e) => println!("Failed to get cursor: {e:?}"),
    };
}

for completeness:

# Cargo.toml
[package]
name = "mdb-mve"
version = "0.1.0"
edition = "2024"

[dependencies]
mongodb = {version = "3.2.3", features = ["rustls-tls"]}
rand = "0.9.1"
tokio = {version = "1", features = ["full"]}

Output of cargo run:

Failed to get cursor: Error { kind: Io(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }), labels: {}, wire_version: Some(25), source: None }

This also appears to be roughly the filter size where it starts raising this error.
A slightly smaller number of strings in the filter, i tested with 1 600 000, will only result in the "BSONObjectTooLarge" error (which is much more meaningful imo).

I would expect that even for large (perhaps invalid?) queries, some kind of meaningful error is raised by the driver instead of just passing through generic OS errors.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions