Skip to content

Diagnosing Neon serverless driver WebSocket connection failures

Covers the two things this error almost always traces back to — a connection string or driver entry point that isn't the one meant for this runtime, and isolating whether the failure is Worker-specific. Does not cover general Postgres server-side connection issues once the WebSocket itself connects successfully — those are covered by the general Postgres playbooks.

Unverifiedno reproductions yetWhy this confidence?
Revision 1published by DevYou curationrevision history
Run the diagnosisEvidence and compatibility

Symptoms

The diagnostic path

8 steps. Every step is written out below in full — the interactive version simply follows the branches for you.

  1. Step 1 · StartEvery WebSocket attempt to Neon failed

    @neondatabase/serverless is built for runtimes, like Cloudflare Workers, that cannot open a raw outbound TCP connection to Postgres — it instead connects through Neon's own WebSocket proxy. This error means every attempt at that WebSocket handshake failed.

    What happens next

    • passed step 2, Confirm the connection string is the one Neon issues for this project, unmodified
  2. Step 2 · TestConfirm the connection string is the one Neon issues for this project, unmodified

    Copy it directly from the Neon project dashboard's connection details rather than reusing a generic postgres:// string meant for a raw TCP client like psql or node-postgres, and rather than hand-editing it.

    What happens next

    • passed step 3, Does the same code and connection string work outside the Worker?
    • failed step 4, Wrong connection string or credentials
    • unknown step 4, Wrong connection string or credentials
  3. Step 3 · TestDoes the same code and connection string work outside the Worker?

    Run the identical query against the identical connection string from a plain Node.js process (with a WebSocket implementation available). If it works there but not inside the deployed Worker, the issue is specific to the Worker runtime rather than the credentials or endpoint.

    What happens next

    • passed step 5, Something in the Worker environment specifically is misconfigured
    • failed step 4, Wrong connection string or credentials
    • unknown step 4, Wrong connection string or credentials
  4. Step 4 · Root causeWrong connection string or credentials

    The string doesn't match what Neon currently issues for this project/branch — it may have been copied from an old branch, a different project, or edited by hand and had something break in the process.

    What happens next

    • passed step 6, Use the connection string and driver import Neon issues for this runtime, unmodified
  5. Step 5 · Root causeSomething in the Worker environment specifically is misconfigured

    Check that the code imports the driver's default export meant for edge runtimes rather than a Node-targeted entry point, and that nothing is calling neonConfig.webSocketConstructor unnecessarily inside the Worker — Workers provide a native global WebSocket, and forcing a Node ws polyfill there can break the handshake instead of fixing it. Also rule out the Worker hitting its own CPU/wall-clock limit before the handshake completes.

    What happens next

    • passed step 6, Use the connection string and driver import Neon issues for this runtime, unmodified
  6. Step 6 · FixUse the connection string and driver import Neon issues for this runtime, unmodified

    Copy the connection string straight from the Neon dashboard, import the driver's default export, and don't set neonConfig.webSocketConstructor unless running in a non-edge Node process that lacks a native WebSocket.

    Read-onlyjavascript
    import { neon } from "@neondatabase/serverless";
    const sql = neon(process.env.DATABASE_URL);
    const rows = await sql`SELECT 1`;

    What happens next

    • passed step 7, Confirm the query succeeds from inside the deployed Worker
  7. Step 7 · Verify the fixConfirm the query succeeds from inside the deployed Worker

    Deploy and run the same query from the actual Worker, not just locally, and confirm it returns without the WebSocket error.

    What happens next

    • passed step 8, Resolved
    • failed step 5, Something in the Worker environment specifically is misconfigured
    • unknown step 5, Something in the Worker environment specifically is misconfigured
  8. Step 8 · EndResolved

    Queries succeed from the deployed Worker using Neon's own connection string and the edge-runtime driver entry point.

Sources

Why this confidence?

What would strengthen it: 6 more independent reproductions. Reproductions from 3 more distinct environments.