Back to Article List

SQL Server errors: A troubleshooting cheat sheet

SQL Server errors: A troubleshooting cheat sheet

Updated and tested 8 October 2026

SQL Server's error messages are unevenly written. Some of them hand you the table, the column and the offending value. Others tell you a connection failed and leave you to work out which of nine things caused it. This page is the list I keep open during an incident, organised by the string you'll paste into a search box, with the cause underneath and the fix after that.

Everything here is grouped by the string the client shows you. Grouping by subsystem would be tidier and less useful, because at the moment you need this page you have a message and nothing else. Where a message deserves its own walkthrough, you get a link to it.

A network-related or instance-specific error occurred while establishing a connection to SQL Server

Cause: the client never completed a TCP connection to the Database Engine. This string is a wrapper, and on its own it's close to useless. The information is in the provider text that follows it, and the number in brackets is what you should search for.

Four inner messages cover most of it. TCP Provider, error: 0 - No such host is known. (Microsoft SQL Server, Error: 11001) is DNS, so the name never resolved. Named Pipes Provider, error: 40 - Could not open a connection to SQL Server (Error: 53) is a network path that wasn't found. TCP Provider: No connection could be made because the target machine actively refused it means you reached the host and nothing was listening on that port. Error 10060, "a connection attempt failed because the connected party did not properly respond after a period of time", is a silent drop, which almost always means a firewall.

Fix: work through enabling remote connections in SQL Server in order, because the order is what saves you time here. Check the service is running before anything else. Then check that TCP/IP is enabled for the instance, and only then argue about the port. The error log prints Server is listening on [ 'any' <ipv4> 1433] at startup and that line settles it. Open the port on the host firewall and on any provider firewall sitting in front of it.

Error Locating Server/Instance Specified

Cause: a named instance lookup failed. The client sent an SSRP datagram to UDP 1434 asking which TCP port host\INSTANCE is on, and no reply came back from SQL Server Browser.

Fix: check the instance name, start the Browser, open UDP 1434 and not TCP 1434, or set a static port and skip the mechanism entirely. For the ordered version with the reasoning attached, see Fixing SQL error 26.

Login failed for user

Cause: the client reached the engine and authentication failed. The client always sees State: 1, which is a placeholder, so the message on your screen cannot tell you why.

Fix: read the real state from the server error log and act on that. Fixing SQL Server error 18456 maps two dozen documented states to their causes, with the T-SQL for each.

Cannot open database "orders" requested by the login. The login failed.

Cause: authentication itself worked. The engine then failed to open the database the connection asked for, either the login's default database or the one named in the connection string. Dropped, renamed, offline, mid-restore or simply a database this login has no user in. The server error log records it as 18456 with state 38, 46 or 126.

Fix: find out what state the database is in first.

SELECT name, state_desc, user_access_desc, is_read_only
FROM sys.databases
ORDER BY name;

ONLINE and MULTI_USER is healthy. RESTORING, OFFLINE, RECOVERY_PENDING or SINGLE_USER is your answer. Naming a database explicitly in the SQL Server connection string does not rescue you here, because several drivers open the login's default database first regardless. Repoint it with ALTER LOGIN [appuser] WITH DEFAULT_DATABASE = [master]; if the database itself is healthy and only the pointer is stale, then fix the user mapping properly.

The server principal is not able to access the database under the current security context

Cause: error 916. The login connects to the instance without trouble and then has no user in the target database, and the guest user has no CONNECT permission there. You'll meet it most often in SSMS Object Explorer, where expanding Databases enumerates every database on the server including ones your login can't touch.

Fix: create a user for that login in that database and give it a role. Microsoft's page for error 916 also lists GRANT CONNECT TO guest; and ALTER DATABASE ... SET TRUSTWORTHY ON; as options. I'd treat both as things to understand and not things to run: granting CONNECT to guest opens that database to every login on the server, and TRUSTWORTHY is a security posture decision that happens to make an error go away.

The certificate chain was issued by an authority that is not trusted

Cause: your driver now encrypts by default and your server is presenting the self-signed certificate it generated at install time. Every major driver flipped this within a few years of each other. Microsoft.Data.SqlClient changed Encrypt to true by default in version 4.0, ODBC Driver 18 changed Encrypt from no to yes, and the JDBC driver made the same change in version 10.2 and called it a breaking change. Nothing changed on your server. The change is in your client library.

Fix: install a certificate the client trusts. On Linux that's two mssql-conf keys and a restart:

sudo /opt/mssql/bin/mssql-conf set network.tlscert /etc/ssl/certs/mssql.pem
sudo /opt/mssql/bin/mssql-conf set network.tlskey /etc/ssl/private/mssql.key
sudo systemctl restart mssql-server

For a lab or a throwaway container, TrustServerCertificate=True in the connection string, or -C on sqlcmd, gets you moving. There is a limit to that trick. With Encrypt=Strict (TDS 8.0) in Microsoft.Data.SqlClient 5.0 and later, TrustServerCertificate is ignored and the certificate is validated regardless.

sqlcmd: command not found

Cause: mssql-tools18 puts sqlcmd and bcp in /opt/mssql-tools18/bin, which is outside the default PATH, and nothing adds it to your shell for you.

Fix: install the package, then put the directory on PATH for good.

sudo apt-get install mssql-tools18 unixodbc-dev
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc
sqlcmd -S localhost -U sa -P '<password>' -C

The full package sequence lives in the SQL Server on Ubuntu install guide. Note the -C on that last line. In mssql-tools18 the -N encryption option defaults to mandatory, which Microsoft calls out as "a breaking change from SQL Server 2022 (16.x) and earlier versions, where the default is -No", so a command that worked on an older box now fails on a self-signed certificate until you trust it with -C or make encryption optional with -No.

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

Cause: one string, two completely different failures, and telling them apart is most of the work. The connection timeout defaults to 15 seconds in Microsoft.Data.SqlClient and fires while the driver is still trying to reach the server. The command timeout defaults to 30 seconds and fires on a query that started fine and never finished.

Fix: if it trips at roughly 15 seconds with no query running, treat it as a network or discovery problem and work the first section of this page. If it trips at roughly 30 seconds mid-query, go looking for blocking:

SELECT session_id, blocking_session_id, wait_type, wait_time, status, command
FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0;

Raising the number is a workaround, and I'd rather fix the plan or the blocker. Microsoft does document one legitimate increase, recommending a connection timeout of at least 30 seconds for Azure SQL Database. Setting CommandTimeout to 0 means wait forever, which is defensible in a nightly job and indefensible in a web request.

String or binary data would be truncated

Cause: a value is longer than the column you're writing it into. Error 8152, and for twenty years it refused to say which column.

Fix: get the better message. SQL Server 2019 introduced error 2628, "String or binary data would be truncated in table '%.*ls', column '%.*ls'. Truncated value: '%.*ls'.", which names the table, the column and the value that didn't fit. It's controlled by a database scoped configuration that defaults to ON:

ALTER DATABASE SCOPED CONFIGURATION SET VERBOSE_TRUNCATION_WARNINGS = ON;

A database restored from an older server keeps its old compatibility level through the upgrade, so a brand new SQL Server 2025 instance will happily serve you the useless 8152 forever. At compatibility level 140 or lower you need trace flag 460 instead. Check with SELECT name, compatibility_level FROM sys.databases; before you conclude the feature is broken, because the whole thing only switches on at database compatibility level 150 or higher.

Could not allocate space for object ... because the 'PRIMARY' filegroup is full

Cause: error 1105, and the full text names all the possibilities: "because the '%.*ls' filegroup is full due to lack of storage space or database files reaching the maximum allowed size. Note that UNLIMITED files are still limited to 16TB." So it's the disk, autogrowth being off, a file that hit its MAXSIZE or an edition cap.

Fix: check which of those it is before you touch anything, because adding a data file to a database that's out of disk helps nobody.

SELECT name, type_desc, size / 128.0 AS size_mb, max_size, growth, is_percent_growth
FROM sys.database_files;

A max_size of -1 is unlimited, 0 means no growth and anything else is a page count you've hit. Microsoft's page for error 1105 lists the actions from there: turn on autogrow, add a file to the filegroup or drop indexes and tables you no longer need. One odd case documented on the same page: when an index spans several files and one of them is full, ALTER INDEX REORGANIZE can raise 1105 where ALTER INDEX REBUILD succeeds.

The Express and Developer edition comparison carries the current per-edition numbers, and on Express the cap is the first thing to check. The limit on the maximum relational database size moved from 10 GB in SQL Server 2022 and earlier to 50 GB in SQL Server 2025, so half the advice online about this is a version behind.

The transaction log for database '...' is full

Cause: error 9002, and the message itself tells you where to look: "To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases." Something is holding the log open and stopping truncation, so adding space to the file will not clear the error.

Fix: ask the column the error points at.

SELECT name, recovery_model_desc, log_reuse_wait_desc
FROM sys.databases
WHERE name = 'orders';

LOG_BACKUP means the database is in FULL recovery and nobody is taking log backups. ACTIVE_TRANSACTION means an open transaction is pinning the log, and DBCC OPENTRAN will find it. AVAILABILITY_REPLICA or REPLICATION point at a synchronisation that isn't completing. Growing the log file does not clear the condition.

The instance of the SQL Server Database Engine cannot obtain a LOCK resource

Cause: error 1204. Locks come from a pool of lock structures and the pool ran out. The lock manager can't use more than 60% of available SQL Server memory, so you get here through memory pressure, through a locks setting that was pinned to a non-default value with sp_configure years ago or through trace flags 1211 or 1224 disabling lock escalation while a query tries to take millions of row locks.

Fix: find the session hoarding them.

SELECT request_session_id, COUNT (*) num_locks
FROM sys.dm_tran_locks
GROUP BY request_session_id
ORDER BY count (*) DESC;

Then the choice is killing the session or fixing the statement behind it, and a huge single-statement DELETE or UPDATE is the usual culprit. Batch it into chunks of a few thousand rows and the problem disappears. Reset a pinned lock configuration back to dynamic with EXEC sp_configure 'locks', 0;, and check trace flags 1211 and 1224, which Microsoft's error 1204 page names as contributors. I have hit 1204 twice and both times it was that same shape of DELETE, so what I know about the trace flag path comes from the documentation.

Job for mssql-server.service failed, or SQL Server on Linux won't start

Cause: systemd reports the failure and tells you almost nothing. The real reason is usually a setting in /var/opt/mssql/mssql.conf that the engine can't honour, a memory limit set below what the instance needs, permissions on /var/opt/mssql that no longer let the mssql user write or a data directory on a file system SQL Server won't use. That last one catches people building custom mounts: the supported file systems are XFS and ext4, and Microsoft's requirements table names BTRFS as unsupported.

Fix: get the status, then get the log, in that order.

systemctl status mssql-server --no-pager
sudo iconv -f UTF-16LE -t UTF-8 /var/opt/mssql/log/errorlog -o /tmp/errorlog.txt
tail -40 /tmp/errorlog.txt

The error log is UTF-16LE, so reading it raw gives you spaced-out nonsense and people conclude the file is corrupt. It isn't. If a configuration setting is what's blocking startup, bring the engine up in minimal configuration mode to get in and undo it:

sudo -u mssql /opt/mssql/bin/sqlservr -f

A failed or half-finished initial setup is the other common case, and rerunning it is safe:

sudo systemctl stop mssql-server
sudo /opt/mssql/bin/mssql-conf setup
sudo systemctl start mssql-server

Your idea deserves better hosting

24/7 support 30-day money-back guaranteeRefund covers the VPS plan on your first order. Cancel anytime
Ciclo de Pagamento

VPS.S1

$5.99 Save  17 %
$4.99 Mensalmente
  • 2 vCPU AMD EPYC
  • 2 GB RAMMEMÓRIA
  • 30 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos

VPS.S3

$14.99 Save  33 %
$9.99 Mensalmente
  • 4 vCPU AMD EPYC
  • 6 GB RAMMEMÓRIA
  • 70 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos

VPS.S4

$19.99 Save  20 %
$15.99 Mensalmente
  • 6 vCPU AMD EPYC
  • 8 GB RAMMEMÓRIA
  • 80 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos

EPYC VPS.P1

$8.99 Save  22 %
$6.99 Mensalmente
  • 2 vCPU AMD EPYC
  • 4 GB RAMMEMÓRIA
  • 40 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos
  • Backup automático grátisInclui um espaço de backup que pode configurar para diário, semanal ou mensal.

EPYC VPS.P2

$16.99 Save  24 %
$12.99 Mensalmente
  • 2 vCPU AMD EPYC
  • 8 GB RAMMEMÓRIA
  • 80 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos
  • Backup automático grátisInclui um espaço de backup que pode configurar para diário, semanal ou mensal.

EPYC VPS.P4

$29.99 Save  23 %
$22.99 Mensalmente
  • 4 vCPU AMD EPYC
  • 16 GB RAMMEMÓRIA
  • 160 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos
  • Backup automático grátisInclui um espaço de backup que pode configurar para diário, semanal ou mensal.

EPYC VPS.P5

$39.99 Save  25 %
$29.99 Mensalmente
  • 8 vCPU AMD EPYC
  • 16 GB RAMMEMÓRIA
  • 180 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos
  • Backup automático grátisInclui um espaço de backup que pode configurar para diário, semanal ou mensal.

EPYC VPS.P6

$59.99 Save  25 %
$44.99 Mensalmente
  • 8 vCPU AMD EPYC
  • 32 GB RAMMEMÓRIA
  • 200 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos
  • Backup automático grátisInclui um espaço de backup que pode configurar para diário, semanal ou mensal.

EPYC VPS.P7

$69.99 Save  29 %
$49.99 Mensalmente
  • 16 vCPU AMD EPYC
  • 32 GB RAMMEMÓRIA
  • 240 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos
  • Backup automático grátisInclui um espaço de backup que pode configurar para diário, semanal ou mensal.

Genoa VPS.G2

$24.99 Save  20 %
$19.99 Mensalmente
  • 2 vCPUAMD EPYC Genoa 4ª geração 9xx4 com 3,25 GHz ou similar, na arquitetura Zen 4. AMD EPYC G4
  • 4 GB DDR5MEMÓRIA
  • 50 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos
  • Backup automático grátisInclui um espaço de backup que pode configurar para diário, semanal ou mensal.

Genoa VPS.G4

$44.99 Save  22 %
$34.99 Mensalmente
  • 4 vCPUProcessador AMD EPYC com núcleos vCPU dedicados, em hardware de servidor empresarial. AMD EPYC G4
  • 8 GB DDR5MEMÓRIA
  • 100 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos
  • Backup automático grátisInclui um espaço de backup que pode configurar para diário, semanal ou mensal.

Genoa VPS.G6

$89.99 Save  22 %
$69.99 Mensalmente
  • 8 vCPUProcessador AMD EPYC com núcleos vCPU dedicados, em hardware de servidor empresarial. AMD EPYC G4
  • 16 GB DDR5MEMÓRIA
  • 200 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos
  • Backup automático grátisInclui um espaço de backup que pode configurar para diário, semanal ou mensal.

Genoa VPS.G7

$159.99 Save  22 %
$124.99 Mensalmente
  • 8 vCPUProcessador AMD EPYC com núcleos vCPU dedicados, em hardware de servidor empresarial. AMD EPYC G4
  • 32 GB DDR5MEMÓRIA
  • 250 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos. incluídos
  • Backup automático grátisInclui um espaço de backup que pode configurar para diário, semanal ou mensal.

AMD Ryzen VPS.R1

$16.99 Save  18 %
$13.99 Mensalmente
  • 1 CPU dedicado AMD Ryzen 9 7950X com 4,5 GHz ou similar, na arquitetura Zen 4. vCPU
  • 4 GB DDR5MEMÓRIA
  • 50 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6 incluídos O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos.
  • Backup automático incluído

AMD Ryzen VPS.R2

$29.99 Save  17 %
$24.99 Mensalmente
  • 2 CPU dedicados AMD Ryzen 9 7950X com 4,5 GHz ou similar, na arquitetura Zen 4. vCPU
  • 8 GB DDR5MEMÓRIA
  • 100 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6 incluídos O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos.
  • Backup automático incluído

AMD Ryzen VPS.R4

$109.99 Save  18 %
$89.99 Mensalmente
  • 8 CPU dedicados AMD Ryzen 9 7950X com 4,5 GHz ou similar, na arquitetura Zen 4. vCPU
  • 32 GB DDR5MEMÓRIA
  • 400 GB NVMeDISCO
  • Largura de banda ilimitada
  • IPv4 & IPv6 incluídos O suporte a IPv6 está indisponível de momento em França, Finlândia ou nos Países Baixos.
  • Backup automático incluído

*VAT excluded.

INCLUDED WITH EVERY PLAN

✓ No setup fees ✓1 Gbps network
✓ Full root access on KVM ✓ Free server monitoring ✓ Firewall management ✓24/7 support

SQL Server logs and diagnostic queries

When the message in front of you isn't on this page, there are three logs worth opening and they answer different questions. The SQL Server error log holds engine events, login failures with their real state and the startup lines that tell you which port and which addresses the instance bound to. The operating system log holds everything that happened before the engine could write anything of its own, which is journalctl -u mssql-server -n 100 --no-pager on Linux and the Application log in Event Viewer on Windows. The SQL Server Agent log, SQLAGENT.OUT in the same Log directory as ERRORLOG, is where a job failure hides while everyone stares at the error log (Agent is disabled by default on Linux, so there may be nothing there to read until you enable it). SQLAGENT.OUT is written in a different format to ERRORLOG, so the timestamps don't line up when you try to correlate a job failure against an engine event. I have written the same small awk script for that three times on three different machines and lost it every time.

For live problems, two queries do most of the work. What's running and what's blocked:

SELECT r.session_id, r.status, r.command, r.wait_type, r.wait_time,
       r.blocking_session_id, t.text
FROM sys.dm_exec_requests AS r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS t
WHERE r.session_id <> @@SPID;

And what build you're really on, because half of the advice you'll find online applies to a different version:

SELECT SERVERPROPERTY('ProductVersion') AS ProductVersion,
       SERVERPROPERTY('ProductLevel')   AS ProductLevel,
       SERVERPROPERTY('ProductUpdateLevel') AS UpdateLevel,
       SERVERPROPERTY('Edition')        AS Edition;

ProductUpdateLevel returns the cumulative update as CU8 or similar, or NULL on an RTM build, which beats looking up a four-part build number by hand. Run it before you start applying fixes from the internet. A surprising number of "this doesn't work" reports come down to a database sitting on compatibility level 130 on an engine from 2025.

Questions?

Where can I find a list of all SQL Server error codes?

Every message is in the sys.messages catalog view, so SELECT message_id, severity, text FROM sys.messages WHERE language_id = 1033 ORDER BY message_id; returns the full list in US English. Microsoft publishes the same catalogue as Database Engine events and errors, split into pages by number range, with links to detail pages for the errors that have one. Search by the number, because the stored text contains placeholders such as %.*ls that the live error fills in.

Jörg L. Günther
About the author

Jörg L. Günther

Jörg has spent much of his career in enterprise software, working first with database deployments and customer environments, then in technical training and documentation. Since then he has written for companies working in virtualisation, database tooling and cloud infrastructure. The subjects he takes on often have a large operational component: database migrations, high-availability setups, storage configuration and procedures carried out on live systems. Jörg lives near Frankfurt. He plays piano and cycles for transport as much as for recreation. He's also been doing woodworking for several years - he says most of the furniture in his study is his own work.

Deploy your next project in seconds

Bring your winning ideas online faster, with modern hardware and unmetered bandwidth. Join a European cloud trusted by thousands of developers and businesses worldwide.