windmill-labs/windmill · error
connection error: ${err instanceof Error ? err.message : err
Error message
connection error: ${err instanceof Error ? err.message : err} What it means
Warning from `wmill datatable serve`, which runs a local Postgres-wire-compatible server that proxies datatable queries to a Windmill workspace. For each accepted TCP connection it runs handleConnection; if that per-connection handler rejects (authentication failure, malformed startup packet, internal error while proxying a query), the server logs `connection error: <message>` and destroys the socket, keeping the server alive for other clients.
Source
Thrown at cli/src/commands/datatable/serve.ts:102
const port =
opts.port ??
(await (getPort as any).default({
port: (getPort as any).portNumbers(
DEFAULT_PORT_RANGE_START,
DEFAULT_PORT_RANGE_END,
),
}));
const password = opts.password ?? randomBytes(12).toString("hex");
const preHashedPassword = await createPreHashedPassword(
DEFAULT_USER,
password,
);
const server = createServer((socket) => {
handleConnection(socket, workspace.workspaceId, preHashedPassword)
.catch((err) => {
log.warn(
colors.yellow(
`connection error: ${err instanceof Error ? err.message : err}`,
),
);
try {
socket.destroy();
} catch {
// ignore
}
});
});
server.on("error", (err) => {
log.error(`server error: ${err.message}`);
process.exitCode = 1;
});
await new Promise<void>((resolve) => server.listen(port, host, () => resolve()));View on GitHub (pinned to e474e8803c)
Solutions
- Check the credentials passed to the client: the password must match the one given to `wmill datatable serve --password ...` (or the prompt); re-run the client with the correct password.
- Verify the workspace/backend is healthy: run any `wmill` command against the same workspace; if those also fail, fix backend connectivity/auth and restart `wmill datatable serve`.
- Capture the full warning on the server side; a malformed-packet error usually means a non-Postgres client (scanner, health probe) hit the port and can be ignored.
- Confirm the client speaks the Postgres wire protocol and start with a simple `psql -h localhost -p <port> -U <user> <datatable>` query to rule out driver-specific handshake features.
Example fix
// before: client connecting without matching password psql postgres://user:wrongpass@localhost:5432/mytable // after psql postgres://user:<the-password-passed-to-serve>@localhost:5432/mytable
Defensive patterns
Strategy: validation
Validate before calling
// before connecting a client, verify credentials and port reachability
const client = new Client({ host: 'localhost', port: SERVE_PORT, user, password });
await client.connect().catch((e) => { console.error('Pre-check failed:', e.message); process.exit(1); });
await client.end(); Type guard
function isConnectionError(e: unknown): e is Error {
return e instanceof Error && /connection error|password|authentication/i.test(e.message);
} Try / catch
client.on('error', (err) => {
if (/password authentication|auth/i.test(err.message)) {
console.error('Wrong password: match the one passed to `wmill datatable serve`.');
} else {
console.error('Query/connection failed:', err.message);
}
// reconnect with backoff for transient network errors
}); Prevention
- Pass the exact password given to `wmill datatable serve` to every connecting client.
- Use a real Postgres-protocol client (psql, standard drivers); avoid health probes sending non-protocol bytes to the port.
- Keep the CLI-to-backend network stable; long-running serve sessions drop on network changes/VPN resets.
- Check `wmill` commands work against the same workspace first to isolate serve-specific vs. backend-wide failures.
When it happens
Trigger: A client connects to the `wmill datatable serve` port and handleConnection rejects: wrong password supplied by the client (preHashedPassword mismatch), unsupported/broken protocol handshake from the client, or an error talking to the Windmill API for that connection (e.g. workspace request failed mid-session).
Common situations: Pointing psql/DBeaver/Grafana at the serve endpoint with the wrong password; a health-check or port scanner opening raw TCP connections that send garbage bytes; network drop between CLI and Windmill backend while a query is in flight; connecting with a Postgres driver feature (e.g. specific auth modes) the proxy doesn't implement.
Related errors
- Could not check backend for git-sync settings: ${(error as E
- Could not fetch datatable schemas: ${err.message}
- Dependency generation failed: ${queueResponse.status} ${queu
- Failed to poll dependencies job ${jobId}: ${e?.message ?? e}
- No response body for SSE stream
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/ea1f8b5d16729022.
Report an issue: GitHub.