Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article provides solutions for common errors and connectivity problems with the go-mssqldb driver.
Start with the simplest checks
Before you enable verbose logging or change pool settings, work through the following list:
- Verify basic reachability: server name, port, firewall rules, and whether SQL Server or Azure SQL is accepting connections.
- Verify authentication inputs: driver name, user name, password, domain format, or
fedauthconfiguration. - Verify TLS settings:
encrypt, certificate paths,hostnameincertificate, and whetherTrustServerCertificateis appropriate for the environment. - Only after connection setup is correct, investigate pool exhaustion, stale connections, retry logic, and slow or blocked query diagnostics.
Use the early sections of this article for connection setup failures. Use the later sections only after connections succeed at least sometimes and then fail under load, after idle time, or during failover.
Connection errors
The following sections cover common connection-related error messages and their solutions.
Unable to open TCP connection
Error message: unable to open tcp connection with host 'localhost:1433': dial tcp 127.0.0.1:1433: connectex: No connection could be made because the target machine actively refused it.
Causes and solutions:
- SQL Server isn't running. Start the SQL Server service.
- TCP/IP isn't enabled. Open SQL Server Configuration Manager and enable TCP/IP under SQL Server Network Configuration > Protocols.
- Wrong port. Verify the port in SQL Server Configuration Manager or use SQL Server Browser for named instances.
- Firewall blocking the port. Add an inbound rule for port 1433 (or your configured port).
Login failed for user
Error message: mssql: login error: Login failed for user '<user>'.
Causes and solutions:
- Incorrect user name or password. Verify the credentials.
- SQL Server authentication is disabled. Enable SQL Server and Windows Authentication mode in server properties.
- The login doesn't exist. Create the login in SQL Server.
- The login doesn't have access to the target database. Grant database access with
CREATE USER.
Certificate validation errors
Error message: TLS Handshake failed: x509: certificate signed by unknown authority
Causes and solutions:
- The server uses a self-signed certificate. Provide the certificate path with the
certificateorserverCertificateparameter, or setTrustServerCertificate=truefor development only. - The CA certificate isn't in the system trust store. Add the CA certificate to the OS trust store or specify it with the
certificateparameter. - Host name mismatch. Use
hostnameincertificateto specify the expected name in the certificate.
For more information, see Encryption and certificates.
Connection timeout expired
Error message: unable to open tcp connection with host '<server>:1433': dial tcp: i/o timeout
Causes and solutions:
- Network connectivity problems. Verify you can reach the server by using
telnet <server> 1433orTest-NetConnection -ComputerName <server> -Port 1433. - DNS resolution failure. Verify the hostname resolves correctly.
- Increase
dial timeoutorconnection timeoutin the connection string.
Authentication errors
The following sections cover authentication error messages.
NTLM authentication failures
Error message: NTLM authentication failed
Causes and solutions:
- Incorrect domain format. Use
DOMAIN\userin theuser idparameter. In URL format, encode the backslash as%5C. - Wrong password. Verify the domain password.
Kerberos authentication failures
Error message: krb5: cannot resolve KDC for realm
Causes and solutions:
- Missing or misconfigured
/etc/krb5.conf. Verify the[realms]section contains the correct KDC address for your domain. - No valid ticket. Run
klistto check for a valid ticket, or runkinitto obtain one. - Keytab file not found. Verify the path in the
krb5-keytabfileparameter.
For more information, see SQL Server and Windows authentication.
Microsoft Entra ID authentication failures
Error message: clientCredentialFromCert: error reading certificate: ... or DefaultAzureCredential: failed to acquire a token
Causes and solutions:
- Incorrect client ID, tenant ID, or client secret. Verify the values in the connection string or environment variables.
- The managed identity isn't configured on the host. Verify the identity in the Azure portal.
- Missing
azureadpackage import. Importgithub.com/microsoft/go-mssqldb/azureadand use theazuresqldriver name.
For more information, see Microsoft Entra ID authentication.
Login failed for user '' (empty user name)
Error message: mssql: login error: Login failed for user ''.
Cause: You used sql.Open("sqlserver", ...) with a fedauth parameter. Entra ID authentication requires the azuresql driver name registered by the azuread package. With the standard sqlserver driver, the fedauth parameter is ignored and the driver attempts SQL authentication with no user name.
Solution: Import the azuread package and use the azuresql driver name:
import _ "github.com/microsoft/go-mssqldb/azuread"
db, err := sql.Open("azuresql",
"sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false")
if err != nil {
panic(err)
}
For more information, see Microsoft Entra ID authentication.
Query errors
The following sections cover query execution error messages.
LastInsertId not supported
Error message: LastInsertId is not supported. Please use the OUTPUT clause or add 'select ID = convert(bigint, SCOPE_IDENTITY())' to the end of your query.
Solution: The go-mssqldb driver doesn't support LastInsertId(). Use an OUTPUT clause or query SCOPE_IDENTITY() separately.
Temporary table not found
Error message: mssql: Invalid object name '#TempTable'.
Cause: Temporary tables are per-connection. If you create a temp table in one call and query it in another, they might use different connections from the pool.
Solution: Use db.Conn(ctx) to pin to a single connection, or wrap operations in a transaction.
For more information, see Stored procedures.
Azure SQL errors
The following sections cover errors specific to Azure SQL Database.
Transient connection error numbers
Use the following shared list as the reference for transient connection-establishment errors and request-path transport failures that are eligible for bounded retry:
The following errors are transient when they occur during connection establishment or while sending a request to the server. Retry on a short, bounded backoff. Errors that persist past a few retries usually indicate a configuration problem (wrong server, missing permissions, exhausted quota) that retry won't fix.
| Error | Message | Troubleshooting |
|---|---|---|
64 |
A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - The specified network name is no longer available.) |
The TCP connection drops mid-handshake. Not a credential failure. If it persists, check for client-side network instability or an intermediate device that drops half-established connections. |
233 |
The client was unable to establish a connection because of an error during connection initialization process before login. |
Pre-login transport or TLS failure. The server commonly returns it when it can't accept the connection (resource exhaustion, max-connections reached, or an unsupported client). Not a credential failure. Verify server health, then check the client login timeout, TLS settings, and client/server TLS version compatibility. |
4060 |
Cannot open database "%.*ls" requested by the login. The login failed. |
The login authenticates but can't open the requested database. Transient causes include the database being in transition (failover, restore, scaling) or auto-paused. Persistent causes (database doesn't exist, login lacks access) won't be fixed by retry; check the database name, login mapping, and database state. |
4221 |
Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. |
The replica isn't available for login because row versions are missing for transactions that were in flight when the replica was recycled. Roll back or commit the active transactions on the primary to resolve the issue. Mitigate by avoiding long write transactions on the primary. |
10053 |
A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An established connection was aborted by the software in your host machine.) |
The local side aborts the connection. Check client-side network health and any local firewall or VPN client. |
10054 |
A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.) |
The remote side sends a TCP reset. Common causes: the peer process crashed, a firewall injected a reset, or the Azure SQL gateway closed an idle connection. For idle-reset patterns, enable TCP keepalive on the client or shorten the connection-pool idle timeout. |
10928 |
Resource ID: %d. The %s limit for the database is %d and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance. |
The database exceeds an Azure SQL resource governance limit. Resource ID 1 indicates the worker limit; Resource ID 2 indicates the session limit. Identify the limit type from the message, then reduce concurrency, scale up the database, or shorten long-running operations holding the resource. |
10929 |
Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d, and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. |
The database is over its minimum guarantee and the underlying server is throttling. Retry typically succeeds when neighbor load drops. Sustained occurrences indicate you need a higher service tier or a less noisy environment. |
40020, 40143, 40166, 40540 |
Reported in the Error code %d slot of error 40197 during failover. |
Sub-codes embedded in a 40197 failover message that some paths surface as the top-level error number. Treat them the same as 40197. |
40197 |
The service has encountered an error processing your request. Please try again. Error code %d. |
A software upgrade, hardware failure, or other failover event in Azure SQL. Reconnecting routes you to a healthy replica. The embedded error code identifies the failover type. If the error persists, capture the session tracing ID and contact support. |
40501 |
The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. |
Azure SQL engine throttling. The recommended floor is a 10-second backoff. Sustained throttling indicates the workload has exceeded the database's resource allocation; scale up the service tier or reduce concurrency. |
40613 |
Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them with the session tracing ID of '%.*ls'. |
The database is unavailable, usually mid-failover or briefly during a scale operation. Retry on a backoff; if it persists past a few minutes, capture the session tracing ID and open a support case. |
42108 |
Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again. |
The dedicated SQL pool (Synapse) is in a paused state. Retry succeeds only after the pool is resumed. Resume the pool explicitly, or schedule the workload to run after the pool resumes. |
42109 |
The SQL pool is warming up. Please try again. |
The dedicated SQL pool is resuming. Retry on a backoff until the pool is online; warmup typically takes a few minutes. |
49918 |
Cannot process request. Not enough resources to process request. The service is currently busy. Please retry the request later. |
The server can't currently allocate enough resources to satisfy the request. Retry on a backoff. If the error persists, scale up the database or elastic pool. |
49919 |
Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". |
Subscription-level concurrency limit on management operations. Reduce parallel create/update calls or stagger them. |
49920 |
Cannot process request. Too many operations in progress for subscription "%ld". |
Subscription-level concurrency limit on operations in flight. Reduce parallelism or wait for in-flight operations to drain. |
Statement-level errors aren't in this list because they fire after the connection is established and the failure leaves the session usable. The most common retryable statement errors are 1205 (deadlock victim) and 1222 (lock-request timeout). Retry the entire transaction rather than the single failing statement.
Error message text is from Azure SQL transient connection errors. Individual drivers maintain their own built-in retry lists; this catalog describes which errors are eligible for retry across SQL Server, Azure SQL Database, Azure SQL Managed Instance, SQL database in Microsoft Fabric, and dedicated SQL pools in Azure Synapse Analytics.
Cannot open server (firewall)
Error message: mssql: login error: Cannot open server '<server>' requested by the login. Client with IP address '203.0.113.42' is not allowed to access the server.
Causes and solutions:
- Your client IP isn't in the Azure SQL firewall rules. Add a firewall rule in the Azure portal: SQL server > Networking > Add a firewall rule.
- If your application runs in Azure, enable Allow Azure services and resources to access this server.
- For private connectivity, configure a private endpoint.
Resource limit reached
Error message: mssql: Resource ID: 1. The session limit for the database is 300 and has been reached.
Causes and solutions:
- Too many concurrent connections for the Azure SQL tier. Lower
MaxOpenConnsin your pool configuration. - Connection leaks (unclosed rows or transactions). Check for missing
defer rows.Close()ordefer tx.Rollback()calls. - Multiple applications sharing the database. Divide the connection limit across all clients.
For Azure SQL connection limits by tier, see Azure SQL Database.
The service is currently busy (throttling)
Error message: mssql: The service is currently busy. Retry the request after 10 seconds. Code: 40501.
Causes and solutions:
- The database is under heavy load. Implement retry logic with exponential backoff.
- The workload exceeds the tier's DTU or vCore capacity. Consider scaling up.
For retry implementation patterns, see Error handling and retry patterns.
Database not currently available
Error message: mssql: Database 'AdventureWorks2025' on server '<server>' is not currently available. Code: 40613.
Cause: Azure SQL is reconfiguring the database (failover, update, or scaling operation). This condition is a transient error.
Solution: Retry the operation. The database typically becomes available within seconds. For more information, see Error handling and retry patterns.
Bad connection errors
A driver: bad connection error means the driver detected that an existing connection is no longer usable. The database/sql pool automatically retries the operation on a fresh connection for non-transactional calls, but operations inside an active transaction fail immediately.
Don't start with this section if the application never connected successfully. driver: bad connection usually points to connection reuse, failover, idle timeout, or network interruptions after the initial connection was already working.
Common causes
| Cause | Typical scenario | Fix |
|---|---|---|
| Azure SQL gateway idle timeout | Connection idle for 30+ minutes behind the Azure gateway. | Set db.SetConnMaxIdleTime(2 * time.Minute) to recycle idle connections before the gateway drops them. |
| Network interruption | Transient network failure between the client and server. | Implement retry logic for non-transactional operations. See Error handling. |
| Server-side session kill | DBA killed the session, or the server was restarted. | Retry. Set db.SetConnMaxLifetime to rotate connections. |
| Azure SQL reconfiguration | Failover, scaling, or patching event dropped the connection. | Set ConnMaxLifetime to 5 minutes or less. Implement retry logic. |
| Long-running transaction timeout | Azure SQL terminated the session (error 40549). | Keep transactions short. Break large operations into smaller batches. |
How database/sql handles bad connections
For calls outside a transaction (db.QueryContext, db.ExecContext), the database/sql pool automatically retries the operation on a new connection when the driver reports a bad connection. This retry is transparent to your code.
For calls inside a transaction (tx.QueryContext, tx.ExecContext), the pool can't retry because the transaction state is lost. Your code must catch the error, roll back, and retry the entire transaction.
Recommended pool settings for Azure SQL
Configure the pool to handle Azure gateway timeouts and failovers:
db.SetConnMaxLifetime(5 * time.Minute) // Rotate connections to recover from failovers.
db.SetConnMaxIdleTime(2 * time.Minute) // Recycle before Azure gateway drops idle connections (30 min).
db.SetMaxIdleConns(10) // Keep warm connections for quick recovery.
db.SetMaxOpenConns(20) // Stay below your tier's connection limit.
For on-premises SQL Server, ConnMaxIdleTime is less critical because there's no gateway idle timeout. However, setting it prevents stale connections after network disruptions.
For detailed configuration guidance, see Azure SQL Database.
Pool exhaustion
Pool exhaustion occurs when all connections in the pool are in use and new callers block waiting for a connection.
Symptoms
- Requests slow down or time out under load.
db.Stats().WaitCountgrows continuously.db.Stats().InUseequalsMaxOpenConns.- Context deadline exceeded errors during peak traffic.
Diagnosis
Add pool monitoring to your application:
stats := db.Stats()
log.Printf("Pool: open=%d inUse=%d idle=%d waitCount=%d waitDuration=%v",
stats.OpenConnections, stats.InUse, stats.Idle,
stats.WaitCount, stats.WaitDuration)
Common causes and solutions
| Cause | How to identify | Fix |
|---|---|---|
rows.Close() not called |
InUse grows over time, never decreases. |
Add defer rows.Close() after every QueryContext. |
| Long-running transactions | InUse stays high during batch processing. |
Keep transactions short. Process large batches in smaller chunks. |
MaxOpenConns too low |
WaitCount grows steadily under normal load after you rule out pinned resources and leaks. |
Increase MaxOpenConns. |
MaxOpenConns not set |
Hundreds of open connections under spike load. | Set MaxOpenConns to a bounded value. |
Goroutine leak calling db.Conn |
InUse grows without corresponding request growth. |
Ensure every db.Conn() result is closed with defer conn.Close(). |
For detailed pool configuration guidance, see Connection pooling.
Slow or blocked query diagnostics
Set query timeouts
Use context deadlines to identify slow queries and prevent blocked SQL calls from pinning connections and stalling callers:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
rows, err := db.QueryContext(ctx, "SELECT * FROM LargeTable WHERE Status = @s",
sql.Named("s", "active"))
if err != nil {
// Check if the error was a timeout.
if ctx.Err() == context.DeadlineExceeded {
log.Println("Query exceeded 5-second timeout")
}
return err
}
defer rows.Close()
For a full performance investigation workflow, including Query Store, DMVs, missing-index analysis, and benchmarking, see Performance tuning.
Deadlock diagnostics
Error message: mssql: Transaction (Process ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Error number: 1205
Solution: Deadlocks occur in concurrent systems. Implement automatic retry logic for error 1205. For a deadlock retry wrapper function, see Transactions.
Prevention strategies:
- Access tables in the same order across all queries.
- Keep transactions short and avoid user interaction during transactions.
- Use
READ COMMITTED SNAPSHOTisolation to reduce lock contention.
Repeated deadlocks on the same query indicate a design problem. Use the deadlock graph (captured through Extended Events or the system health session) to identify the competing statements and lock types. For a full walkthrough, see the Deadlocks guide. For deadlock handling strategies in Go, see Deadlock handling and Handle deadlocks.
Certificate errors with containers (Go 1.23 and later versions)
Error message: x509: negative serial number
Cause: Go 1.23 strictly enforces RFC 5280. The self-signed certificate that SQL Server generates in Docker containers uses a negative serial number, which Go rejects.
Solutions:
- For test environments, add
TrustServerCertificate=trueto skip certificate validation, orencrypt=disableto turn off encryption entirely. - For CI/CD, set the
GODEBUG=x509negativeserial=1environment variable to restore the pre-Go 1.23 behavior without changing your connection string. - In
go.mod(Go 1.23 and later versions), add agodebug x509negativeserial=1directive to apply the override at build time.
Caution
Don't use TrustServerCertificate=true or encrypt=disable in production. These options disable security checks. For production, use a properly signed certificate.
SHA-1 certificate errors (Go 1.24 and later versions)
Error message: tls: handshake failure or TLS Handshake failed: EOF when connecting to older SQL Server instances.
Cause: Go 1.24 disallows SHA-1 signature algorithms in TLS certificates by default. Older SQL Server versions and some on-premises installations use certificates signed with SHA-1.
Solutions:
- Reissue the server certificate with SHA-256 or later (recommended).
- Set the
GODEBUG=tlssha1=1environment variable to temporarily re-enable SHA-1 support. - In
go.mod(Go 1.23 and later versions), add agodebug tlssha1=1directive.
When to use encrypt=disable vs. TrustServerCertificate=true
| Setting | What it does | When to use |
|---|---|---|
TrustServerCertificate=true |
Encrypts traffic but skips certificate validation. | Local development and testing where the server uses a self-signed certificate. |
encrypt=disable |
Sends traffic in plaintext (no TLS). | Legacy environments where TLS isn't available. Not recommended. |
encrypt=strict |
TDS 8.0 with full TLS validation from the first byte. | Production on SQL Server 2022 or Azure SQL. |
For more information, see Testing and Encryption and certificates.
Encoding and collation issues
Implicit conversion warnings
If you pass string parameters (sent as nvarchar) to varchar columns, SQL Server performs an implicit conversion that can prevent index usage.
This example continues the database/sql and mssql setup from earlier snippets in this article.
Solution: Use mssql.VarChar for varchar columns:
db.QueryContext(ctx, "SELECT * FROM Production.Product WHERE ProductNumber = @p1",
mssql.VarChar("FR-R92B-58"))
CharsetToUTF8 error with non-Latin characters
Error message: CharsetToUTF8: ... when querying varchar columns containing Chinese, Japanese, or other non-Latin characters stored in a collation like SQL_Latin1_General_CP1_CI_AS.
Cause: The driver attempts to convert the column's code page to UTF-8, but the stored bytes don't match the collation's expected encoding.
Solutions:
- Use
nvarcharinstead ofvarcharfor columns that store non-Latin text.nvarcharstores data as UTF-16 and avoids code page conversion. - If you can't change the column type, verify the database collation supports the character set you're storing.
Enable diagnostic logging
Use the log connection parameter to enable driver-level logging:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=63
Log flags are bitmask values: 1 (errors), 2 (messages), 4 (rows), 8 (SQL), 16 (params), 32 (transactions), 64 (debug). Combine values by adding them (for example, 63 = all except debug, 127 = all).
For programmatic logging, use SetLogger or SetContextLogger. See Logging and diagnostics.
Troubleshooting checklist
| Symptom | First step |
|---|---|
| Connection refused | Verify SQL Server is running and TCP/IP is enabled. |
| Login failed | Check credentials and authentication mode. |
| Certificate error | Check server certificate or set TrustServerCertificate=true (dev only). |
| Connection timeout | Verify network path with Test-NetConnection. Check firewall rules. |
| Azure SQL firewall | Add your IP to Azure SQL firewall rules. |
| Throttling errors | Implement retry with exponential backoff. Scale up the tier. |
| Bad connection | Set ConnMaxIdleTime below 30 minutes for Azure SQL. Implement retry logic. |
| Pool exhaustion | Monitor db.Stats(). Fix unclosed rows/transactions. Increase MaxOpenConns. |
| Slow queries | Set context timeouts. Query DMVs for expensive queries. |
| Deadlocks | Implement retry on error 1205. Access tables in consistent order. |
| Implicit conversion | Use mssql.VarChar for varchar columns. |