SQL Server instance down: no response on port 1433 and where to look first
Your availability probe just fired: TCP connect plus SELECT 1 against port 1433 has failed three or more times over at least 60 seconds. Before you restart anything, separate the two failure modes that get lumped together as “SQL Server is down”. They have different causes, different fixes, and different blast radii.
Mode one: no TCP connect at all. The listener is not accepting connections on 1433 (or the named instance’s dynamic port). The service is stopped, the host is down, the network path is broken, or the listener is misconfigured, commonly after an AlwaysOn failover. The engine is not there to talk to.
Mode two: TCP connects but the query hangs. The engine is alive but cannot make progress. Worker thread exhaustion from a blocking cascade, severe resource pressure, or runaway parallelism are the usual suspects. Restarting SQL Server here destroys the forensic state you need and only buys time until the next storm. Use the Dedicated Administrator Connection (DAC) to diagnose, not restart.
What the probe means
The Instance Responsiveness signal treats 3+ consecutive probe failures over 60 seconds or more as a PAGE-level condition. A single missed probe is not an outage. Brief scheduler spikes, network blips during cold start, and backup stress can all drop one probe.
A probe should be layered, not just a TCP connect:
- Open a TCP connection to the listener port (1433 for a default instance, the configured static or dynamic port for a named instance).
- Authenticate.
- Execute a trivial query like
SELECT 1with a 10-second timeout.
Each layer that fails points at a different fault:
- TCP RST or timeout: the listener is not there. Service stopped, host down, network partition, or listener misconfigured.
- TCP connect succeeds, query hangs: the engine accepted the connection but cannot schedule the worker. Worker exhaustion or blocking.
- Authentication fails with a successful TCP connect: credentials or certificate problem, not an outage.
- Connection succeeds in
masterbut fails scoped to a specific database: that database is offline, restoring, or suspect. The instance is up.
A common false positive: the probe uses Initial Catalog=<prod_db> and that database is offline. The instance is healthy, every other database is online, and the alert is misleading. Scope probes to master for liveness and check database state separately.
flowchart TD
A[Probe fails] --> B{TCP connect succeeds?}
B -- No --> C[Service down / network / listener]
C --> C1[systemctl status mssql-server]
C --> C2[Error log + Event Log]
C --> C3[OOM killer on Linux]
C --> C4[AG listener routing]
B -- Yes --> D[Engine alive, not progressing]
D --> D1[Use DAC: sqlcmd -A]
D --> D2[THREADPOOL waits + work_queue_count]
D --> D3[Blocking chain head]Common causes
| Cause | What it looks like | First thing to check |
|---|---|---|
| Service stopped or crashed | TCP connect refused immediately; nothing listening on 1433 | systemctl status mssql-server (Linux) or Services.msc (Windows); error log tail |
| Host down or network partition | TCP connect times out; no RST | Host ping, Test-NetConnection, switch or firewall status |
| Listener misconfigured after AG failover | Connect to listener name fails, direct replica connect works | sys.dm_hadr_availability_replica_states, listener IP routing |
| Named instance and SQL Browser down | Connect by name fails with “network-related or instance-specific error”; direct port works | UDP 1434 reachable, SQL Browser service running |
| Worker thread exhaustion | TCP connect succeeds, SELECT 1 hangs | DAC session, THREADPOOL waits, work_queue_count per scheduler |
| Blocking cascade | Same as worker exhaustion, often preceded by lock waits | sys.dm_exec_requests for head blocker, LCK_M_* waits |
| Database offline or suspect | Connection to master works, probe scoped to one DB fails | sys.databases.state_desc |
| TLS or certificate expiry | TCP connects, SSL handshake fails or login fails | Certificate expiry in error log, sys.certificates for AG endpoints |
| OOM killer terminated the engine (Linux) | Service was running, now gone; TCP connect refused | /var/log/messages for OOM entries, memory.memorylimitmb in mssql.conf |
| Hostname longer than 15 chars on Linux | Install or restart fails oddly, listener does not bind | hostname length |
Quick checks
Run these in order. All are read-only.
# 1. Layered probe from a client (use the right port for named instances)
sqlcmd -S <host>,1433 -Q "SELECT 1" -l 10
# Windows: Test-NetConnection -ComputerName <host> -Port 1433
# 2. Service status on Linux
sudo systemctl status mssql-server
sudo journalctl -u mssql-server --since "30 min ago" --no-pager
# 3. Service status on Windows (elevated)
Get-Service -Name 'MSSQLSERVER','SQLSERVERAGENT','SQLBrowser'
Get-WinEvent -FilterHashtable @{LogName='Application'; ProviderName='MSSQLSERVER'; StartTime=(Get-Date).AddHours(-1)} -MaxEvents 50
# 4. Tail the SQL Server error log
# Linux:
sudo tail -n 200 /var/opt/mssql/log/errorlog
# Or from a working SQL connection:
EXEC sp_readerrorlog 0, 1, 'Error';
# 5. Check for OOM kills on Linux
sudo grep -i "out of memory\|killed process\|mssql\|sqlservr" /var/log/messages /var/log/syslog 2>/dev/null | tail -n 50
# 6. DAC connection - bypasses worker pool limits
sqlcmd -S admin:<host> -U sa -P '<password>' -Q "SELECT 1"
# or:
sqlcmd -S <host> -U sa -P '<password>' -A
# If the login's default database is offline, force master:
sqlcmd -S admin:<host> -U sa -P '<password>' -A -d master
# 7. Confirm the listener port is actually bound
# Linux:
sudo ss -ltnp | grep -E '1433|sqlservr'
# Windows (elevated):
netstat -ano | findstr :1433
# 8. SQL Browser for named instances (UDP 1434)
# Linux:
sudo ss -lunp | grep 1434
# Windows:
Get-Service SQLBrowser
Get-NetUDPEndpoint -LocalPort 1434 -ErrorAction SilentlyContinue
-- 9. If AlwaysOn is in play, check replica and listener state from a working session
SELECT ag.name, ar.replica_server_name, ars.role_desc,
ars.connected_state_desc, ars.synchronization_health_desc
FROM sys.dm_hadr_availability_replica_states ars
JOIN sys.availability_replicas ar ON ars.replica_id = ar.replica_id
JOIN sys.availability_groups ag ON ar.group_id = ag.group_id;
-- 10. Database state for the database the probe is scoped to
SELECT name, state_desc, user_access_desc, log_reuse_wait_desc
FROM sys.databases
WHERE state_desc <> 'ONLINE';
How to diagnose it
Confirm the failure mode. From a client on the same subnet as the SQL host, run the layered probe. If TCP connect fails, treat this as a listener-or-below problem. If TCP connects but the query hangs, treat it as an engine problem.
Check the service first, not the application. On Linux:
systemctl status mssql-server. On Windows: Services.msc orGet-Service MSSQLSERVER. If the service is stopped, do not start it yet. Read the tail of the error log and the system journal first. The reason it stopped is more important than the fact it stopped.Read the error log. The error log records the shutdown reason, the last startup, I/O errors (823, 824, 825), stack dumps, and TempDB creation failures. SQL Server will refuse to start if TempDB cannot be created. Look for storage errors around the last shutdown timestamp.
On Linux, check for OOM kills. The kernel OOM killer can terminate
sqlservrsilently from SQL Server’s perspective. Check/var/log/messagesfor “Out of memory” or “Killed process” entries mentioningmssqlorsqlservr. If found, the fix ismemory.memorylimitmbin/var/opt/mssql/mssql.conf(default is 80% of physical RAM), not a restart.If the service is up and TCP connect works, the problem is the engine. Open a DAC session. On the default instance the DAC listens on TCP 1434 directly. On SQL Server Express the DAC is not enabled unless trace flag 7806 was set at startup. DAC is local-only by default; for remote use,
sp_configure 'remote admin connections', 1must already have been run, so plan for console access to the host when you actually need it.In the DAC session, check the four horsemen of unresponsiveness: worker threads, blocking chains, memory grants, and scheduler runnable backlog.
-- Worker thread state and THREADPOOL waits
SELECT max_workers_count FROM sys.dm_os_sys_info;
SELECT scheduler_id, current_tasks_count, runnable_tasks_count,
active_workers_count, work_queue_count
FROM sys.dm_os_schedulers
WHERE status = 'VISIBLE ONLINE';
SELECT wait_time_ms, waiting_tasks_count
FROM sys.dm_os_wait_stats WHERE wait_type = 'THREADPOOL';
-- Head blocker
SELECT r.session_id, r.blocking_session_id, r.wait_type,
r.wait_time / 1000 AS wait_seconds, t.text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.blocking_session_id <> 0
ORDER BY r.wait_time DESC;
If nothing is wrong with the engine, suspect the path. For named instances, confirm SQL Browser is running and UDP 1434 is reachable from the client subnet. For AG listeners, confirm the listener IP is online on the current primary and the routing list is correct.
If
masterconnects but a database-scoped probe fails, the database is offline, restoring, or suspect. Checksys.databases.state_descand the error log around the state change. The instance is not down; one database is. Update the probe.
Metrics and signals to monitor
| Signal | Why it matters | Warning sign |
|---|---|---|
Instance responsiveness probe (TCP + SELECT 1) | The actual outage signal | 3+ failures over 60s |
MSSQLSERVER or mssql-server service state | Catches crashes, OOM kills, manual stops | Not running |
| Error log critical entries (823, 824, 825, stack dumps, severity 20+) | Hardware and engine failures that precede a crash | New entries since last sweep |
max_workers_count and active workers | Worker pool approaching exhaustion | Active above 80% of max |
THREADPOOL waits with work_queue_count > 0 | New connections will queue; effective outage | Sustained 60s or more |
| Blocking chain depth and head blocker status | Cascades into worker exhaustion | Sleeping head blocker, chain greater than 10 |
sys.dm_os_schedulers.runnable_tasks_count | In-engine CPU queue, cleaner than OS CPU | Sustained above 1 per scheduler |
Database state (state_desc) | Database-scoped outage without instance outage | Any non-ONLINE state |
AG replica connected_state_desc and synchronization_health_desc | Failover capability and listener routing | DISCONNECTED or NOT_HEALTHY |
| Disk space on data, log, and TempDB volumes | Preventable outage cause | Below 20% or below next autogrow increment |
| Linux OOM events | Engine killed by kernel | OOM entries mentioning mssql or sqlservr |
| Certificate expiry (AG endpoints, TDE) | Connections fail when certs lapse | Less than 90 days to expiry |
Fixes
Service stopped or crashed
Read the error log before you restart. The crash reason is the recurrence risk. If you see 823, 824, or stack dumps, the storage or the engine is the problem, and a restart may not even succeed. If TempDB could not be created, free space or fix permissions on the TempDB volume first. Only after you understand the cause, start the service (sudo systemctl start mssql-server or Start-Service MSSQLSERVER).
Host or network partition
If TCP connect times out from the probe host but works from the SQL host itself, the path is the problem. Check firewalls, switch health, and DNS. For named instances, confirm SQL Browser is running and UDP 1434 is not blocked between the client and the SQL host. For AG listeners, confirm the listener IP is hosted on the current primary and client routing reaches it.
Listener misconfigured after AG failover
Confirm the listener object is registered on the new primary. On SQL Server 2022 pre-CU24, listener object errors at failover are a known issue; apply CU24 or later. Validate the listener routing list and that the WSFC or Pacemaker resource is online.
Worker thread exhaustion or blocking cascade
Use the DAC to identify the head blocker. If the head blocker is a sleeping session with an uncommitted transaction, killing it is usually the right move, but the rollback may take as long as the original transaction. If the exhaustion is from parallel queries (many workers per request), check MAXDOP and Cost Threshold for Parallelism. If external waits dominate (linked servers, CLR), the offending session is in preemptive mode. Killing it forces rollback.
Database offline or suspect
If a database is offline because someone set it offline, bring it back online with ALTER DATABASE <name> SET ONLINE. If it is suspect, do not set it into EMERGENCY and run repair without understanding the cause. DBCC CHECKDB WITH REPAIR_ALLOW_DATA_LOSS is a last resort that silently drops data; restore from backup if at all possible. Update the probe to use master for the liveness check, and alert on database state separately.
OOM killer on Linux
Configure memory.memorylimitmb in /var/opt/mssql/mssql.conf to a value that leaves headroom for the OS and any co-located processes. The default of 80% of physical RAM is too high if other processes run on the host. Tune mssql.conf and restart the service to apply. Consider lowering oom_score_adj for the mssql process so the kernel prefers to kill other processes.
TLS or certificate expiry
Renew the certificate. For AG endpoints, the endpoints reconnect once the new cert is in place and the endpoints are altered to use it. For client TLS, the new cert must be trusted by clients.
Prevention
- Scope liveness probes to
master. Alert on individual database states separately so a single offline database does not page as “instance down”. - On Linux, set
memory.memorylimitmbdeliberately, not at the default. Monitor/var/log/messagesfor OOM activity. - Enable remote DAC before you need it:
EXEC sp_configure 'remote admin connections', 1; RECONFIGURE;. Document the DAC connection string in your runbook. - For named instances, monitor SQL Browser service state and UDP 1434 reachability from the client subnet.
- For AG deployments, run scheduled failover drills. A failover you have never tested is a failover you cannot rely on. Apply SQL Server 2022 CU24 or later if you are on that branch.
- Monitor worker thread utilization,
THREADPOOLwaits, andrunnable_tasks_countso worker exhaustion is caught before the probe fails. - Track certificate expiry on AG endpoints and TDE protectors with at least 90 days of lead time.
- Set up error log alerting for 823, 824, 825, and stack dumps. These are the precursors to crashes and data loss.
- On Linux, keep hostnames at 15 characters or fewer. Longer hostnames can cause install or restart failures that look like listener problems.
How Netdata helps
- The SQL Server collector surfaces instance responsiveness, database states, worker thread utilization, wait statistics, and AG health at per-second granularity, so a probe failure can be correlated against the engine’s internal state at the second it stopped responding.
- The dashboard pairs
THREADPOOLwaits,work_queue_countper scheduler, and blocking chain depth, letting you distinguish “engine gone” from “engine saturated” in seconds rather than minutes. - Per-second collection catches leading indicators (rising workers, growing blocking chains, climbing log usage) before the probe fails, and anomaly detection flags deviations from the per-database, per-hour baseline.
- Error log and Windows Event Log forwarding into Netdata gives a single timeline view: storage errors, OOM kills, AG state changes, and probe failures align.
- Host-level disk, memory, and CPU metrics are collected alongside SQL Server metrics, so an OS-level cause (OOM kill, full disk, CPU steal) is not hidden behind an engine-level symptom.
Netdata’s Microsoft SQL Server monitoring with Netdata brings these signals together with per-second metrics and ML anomaly detection.
Related guides
- SQL Server blocking chains: finding the head blocker before workers run out
- SQL Server buffer cache hit ratio low: when the working set no longer fits in memory
- SQL Server user connections climbing: connection pool leaks and retry storms
- SQL Server CPU utilization high: telling query load apart from a bad plan
- SQL Server CXPACKET and CXCONSUMER waits: parallelism, MAXDOP, and what is actually wrong
- SQL Server Error 1205: transaction was deadlocked and chosen as the deadlock victim
- SQL Server Error 701: there is insufficient system memory to run this query
- SQL Server Error 823 and 824: I/O and logical consistency errors
- SQL Server Error 825: read-retry succeeded and the disk is failing
- SQL Server Error 9002: the transaction log for the database is full
- SQL Server high compilations per second: plan cache pollution and CPU burn
- How Microsoft SQL Server actually works in production: a mental model for operators






