Connecting a Node.js web server to Microsoft SQL Server using the mssql package is usually straightforward. However, things can get tricky when dealing with named instances like SQL Server Express (e.g., MYSERVERNAME\SQLEXPRESS01). A common frustration is running into the following timeout error:

ConnectionError: Failed to connect to MyServerName\SQLEXPRESS01 in 15000ms
code: 'ETIMEOUT', name: 'ConnectionError'

This happens even when direct command-line utilities like sqlcmd connect without any issues. In this guide, we will break down why this happens and explore the exact steps needed to fix it.

Why Does This Error Happen?

When you connect using sqlcmd locally, it often uses local named pipes or shared memory protocols. Node.js (via the underlying tedious driver in mssql), however, connects strictly over TCP/IP.

By default, SQL Server Express disables TCP/IP, or it assigns dynamic TCP ports. When using named instances, Node.js needs to query the SQL Server Browser Service over UDP port 1434 to discover which dynamic TCP port your instance is listening on. If TCP/IP is disabled, the SQL Server Browser is stopped, or the firewall blocks the necessary ports, Node.js will hang until it hits the 15-second timeout.

Step-by-Step Solutions

1. Enable TCP/IP Protocol in SQL Server

By default, SQL Server Express disables TCP/IP connections. To enable it:

  1. Open SQL Server Configuration Manager.
  2. Expand SQL Server Network Configuration > Protocols for SQLEXPRESS01.
  3. Right-click TCP/IP and select Enable.
  4. Restart the SQL Server (SQLEXPRESS01) service.

2. Enable and Start the SQL Server Browser Service

Because you are targeting an instance name (SQLEXPRESS01) rather than a fixed port, Node.js must look up the dynamic port via the SQL Browser:

  1. In SQL Server Configuration Manager, click on SQL Server Services.
  2. Find SQL Server Browser. If its state is Stopped, right-click it, go to Properties, change the start mode to Automatic, and start the service.

3. Configure a Static Port (Recommended Alternative)

Rather than relying on dynamic ports and the SQL Browser service, assigning a dedicated static port is often more reliable and faster for web services.

  1. In SQL Server Configuration Manager, open Protocols for SQLEXPRESS01 > double-click TCP/IP.
  2. Go to the IP Addresses tab and scroll down to the IPAll section.
  3. Clear any value in TCP Dynamic Ports and set TCP Port to 1433 (or another port like 14333 if 1433 is in use).
  4. Restart the SQL Server service.

If you assign a static port, update your Node.js configuration to use the port property directly instead of the instance name:

const config: sql.config = {
    user: serviceAccountUsername,
    password: serviceAccountPassword,
    server: 'MyServerName', // or IP address
    port: 1433,             // specify the static port
    database: 'DB1',
    options: {
        encrypt: true,
        trustServerCertificate: true
    }
};

4. Verify Windows Firewall Rules

If your Node.js server runs on a different machine (or inside a container/WSL), make sure the host firewall allows traffic:

  • TCP Port: Port 1433 (or your configured custom port).
  • UDP Port: Port 1434 (required for SQL Server Browser if using named instances).

5. Update Your Node.js / TypeScript Connection Code

Ensure that you pass configuration settings properly without mutating shared objects across requests. Here is an improved version of your TypeScript connection function:

import sql from 'mssql';

export async function getDbConnection(serverName: string, instanceName: string, databaseName: string) {
    const config: sql.config = {
        user: process.env.ServiceAccountUsername,
        password: process.env.ServiceAccountPassword,
        server: serverName,
        database: databaseName,
        options: {
            instanceName: instanceName, // e.g. 'SQLEXPRESS01'
            encrypt: true,
            trustServerCertificate: true,
            connectTimeout: 30000 // Increase timeout if needed
        }
    };

    return await sql.connect(config);
}

Summary

The ETIMEOUT connection error in Node.js when targeting SQL Server Express almost always points to network protocol configuration. Enabling TCP/IP and starting the SQL Server Browser service (or switching to a static port such as 1433) will resolve the issue and allow your API requests to execute stored procedures successfully.