Recently, I reviewed a customer case where an application intermittently reported: com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set. The issue occurred during a specific period and was no longer reproducible.
Instead of starting troubleshooting from the database side, my first objective was to answer a simpler question: Who is actually generating this error: SQL Server Engine or the JDBC driver?
Step 1 – Is this a SQL Server Engine error?
A useful first check is sys.messages.
SQL Server exposes its system-defined error messages through this catalog view, so I can search for the reported text: SELECT message_id, severity, text FROM sys.messages WHERE text LIKE ‘%did not return a result set%’;
The sys.messages catalog view contains the system error messages available in SQL Server. If I find the error there, I have a good reason to continue investigating the SQL Server Engine error number, severity, conditions, and associated diagnostics.
In this case, however, the message led me in another direction.
An important caveat: not finding a message in sys.messages does not by itself prove that SQL Server or Azure SQL Database cannot be involved. Errors can also originate from drivers, operating systems, network libraries, gateways, application frameworks, or custom code.
However, it is a very useful way to reduce the troubleshooting scope.
Step 2 – Follow the component mentioned in the exception
The exception class itself provided the next clue: com.microsoft.sqlserver.jdbc.SQLServerException. This pointed directly to the Microsoft JDBC Driver for SQL Server, so instead of continuing with database-side diagnostics, I decided to inspect the driver implementation.
The driver is open source and its code is available in the Microsoft GitHub repository: microsoft/mssql-jdbc
The Java source code is located under: src/main/java/com/microsoft/sqlserver/jdbc/. This directory contains the implementation of the JDBC driver, including connection handling, statements, prepared statements, result sets, exceptions, and resource messages.
Step 3 – Search for the exact error text
I searched the source code for: The statement did not return a result set. The message is defined in: src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java as: {“R_noResultset”, “The statement did not return a result set.”}
This was already an important finding. The exact message is defined inside the JDBC driver.
Step 4 – Search for R_noResultset
The next step was to search for the resource identifier: R_noResultset
This led to: src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java where the driver contains the following logic:
if (EXECUTE_QUERY == executeMethod && null == resultSet)
{
SQLServerException.makeFromDriverError( connection, this, SQLServerException.getErrString(“R_noResultset”), null, true);
}
Now the meaning of the customer’s error becomes much clearer. The application executed the statement using an operation equivalent to: executeQuery() but after processing the response: resultSet == null
Therefore, the JDBC driver raises this exception when executeQuery() is used but, after processing the response, no ResultSet is available (resultSet == null).
Step 5 – Now investigate the database execution
Only at this point would I move deeper into the SQL execution. The question is no longer: Why did SQL Server fail?
It becomes: Why did this execution not return the ResultSet that the JDBC application expected?
For example: IF Condition = 1 BEGIN SELECT … END
One execution might produce: Condition = TRUE -> SELECT -> ResultSet -> executeQuery() succeeds
while another could produce: Condition = FALSE -> No SELECT -> No ResultSet -> JDBC raises the exception
This could also explain why the customer’s issue was intermittent. At that stage I would investigate the stored procedure, parameters, conditional branches, DML operations, multiple result sets, and the application’s use of executeQuery(), executeUpdate(), or execute().
The troubleshooting lesson
The most useful part of this case was not only understanding this particular exception.
It was the troubleshooting process: Customer error -> Who generated it? -> Search sys.messages -> Engine error?
- YES -> SQL Server troubleshooting
- NO / unclear -> Identify client component -> Search its source code -> Locate exact message -> Find where it is raised -> Understand the condition -> Return to SQL Server with a focused hypothesis
When the client component is open source, its source code can become another diagnostic tool. Instead of collecting large amounts of database telemetry, we can first determine which component generated the error and why.
One final consideration: always check the JDBC driver version used by the customer and, when possible, inspect the corresponding GitHub release or tag rather than relying exclusively on the current main branch. Sometimes a few lines of source code can significantly reduce hours of troubleshooting.


