Skip to content

sqlx query! and friends macros throw constant connection errors when using Docker #4073

@tgrushka

Description

@tgrushka

I have found these related issues/pull requests

#3939 -- no idea why closed, it is not fixed -- maybe not 100% the same issue, but seems very closely related

Description

Constantly receive:

error communicating with database: expected to read 5 bytes, got 0 bytes at EOF

macro panics in VS Code when editing a query after successful connection to the Docker databsae the first time. The database is still running and there are no connection problems from the app itself. This error only occurs in the IDE on sqlx::query! and related macro calls.

This occurs for me > 95% of the time after the initial load or Developer: Reload Window of the IDE. Even if I leave the file and come back to it, it will have this error.

It is quite likely this could be due to a very flaky, intolerant connection attempt by the sqlx macro with a very short timeout, likely for better performance, but seems no way the user can customize this timeout or its other connection parameters.

Reproduction steps

  1. Create a sqlx project as usual.
  2. Set up a docker-compose.yaml as follows:
services:
  postgres:
    image: postgres:17
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 3s
      timeout: 1s
      retries: 5
  1. Place database parameters in your .env file.
  2. Add a DATABASE_URL to your .env file:
DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}
  1. Use a simple sqlx::query macro such as:
#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv_override().ok();

...

    let pg = build_pg_pool_with_options(
        &database_url,
        &PgPoolOptions::new().max_connections(10),
        &HashMap::new(),
    )
    .await?;
    println!("Connected to database: {}", sanitize_url(&database_url));

...

    let mut tx = pg.begin().await?;

    sqlx::query!(r#"SELECT now(), 1 as "one""#)
        .fetch_optional(&mut *tx)
        .await?;

}
  1. You may or may not have the error on #[tokio::main] at this point.
  2. Run Developer: Reload Window command just to be sure.
  3. Note it compiles just fine. If it doesn't connect after the reload, there's something wrong with the DATABASE_URL, Docker postgres container, or other setup, not sqlx itself.
  4. Now, make a simple change to the same query (don't add a new one):
    sqlx::query!(r#"SELECT now(), 2 as "two""#)
        .fetch_optional(&mut *tx)
        .await?;
  1. Save.
  2. ERROR! on #[tokio::main]:
error communicating with database: expected to read 5 bytes, got 0 bytes at EOF

SQLx version

0.8.5

Enabled SQLx features

["chrono", "json", "postgres", "uuid", "migrate", "runtime-tokio-rustls", "bigdecimal"]

Database server and version

Docker container: PostgreSQL 17.6 (Debian 17.6-2.pgdg13+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit

Operating system

Host: macOS 15.6.1, Container: Debian 17.6-2.pgdg13+1

Rust version

rustc 1.92.0-nightly (695857bc3 2025-10-21)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions