| Bug #119924 | Connector J times out after double the specified socketTimeout value | ||
|---|---|---|---|
| Submitted: | 19 Feb 12:06 | Modified: | 22 Feb 19:39 |
| Reporter: | Etienne Hardy | Email Updates: | |
| Status: | Not a Bug | Impact on me: | |
| Category: | Connector / J | Severity: | S3 (Non-critical) |
| Version: | 9.6.0 | OS: | Any |
| Assigned to: | Filipe Silva | CPU Architecture: | Any |
[22 Feb 19:39]
Filipe Silva
Hi Etienne Hardy, Thank you for your interest in MySQL Connector/J and for taking the time to file this report. What you are observing is expected behavior and can look like the configured socketTimeout is being "doubled," but what's happening is that the driver may block on socket reads in two distinct phases: - During query execution (waiting for the server response). - During connection cleanup/close after the timeout. When TLS is enabled, closing the connection involves a graceful TLS shutdown, which requires reading from the socket and is therefore also subject to the same read timeout. You can see this by setting `socketTimeout=2000` and running a query such as `SELECT SLEEP(3)`. The query read will time out at ~2 seconds, and then the subsequent close/cleanup path blocks briefly while completing TLS shutdown—potentially adding additional elapsed time before the exception is surfaced/logged. Depending on timing (e.g., the server finishing the response while the client is closing), this additional delay may be shorter than a full timeout, but it can still make the total observed time exceed the configured `socketTimeout`. If you disable TLS (`sslMode=DISABLED`), the close path does not incur the same additional blocking behavior, since the TLS shutdown semantics are not involved. This is consistent with how Java TLS sockets behave during graceful shutdown. Given the above, we don't consider this a Connector/J defect in itself; the exception message reflects the total elapsed time for the operation including cleanup. That said, if you'd like the driver to avoid (or cap) any additional wait during close after a read timeout, that would be best tracked as a feature request, since it implies changing shutdown/cleanup behavior and may have tradeoffs. I'll close this report as "not a bug" for now. If you have a reproducer showing the total time consistently exceeding the configured timeout without being attributable to TLS shutdown/cleanup, please reopen the report with those details.

Description: Whatever value we specify for socketTimeout, the timeout will instead be after twice that time. To validate, we have implemented a piece of code that does a "select sleep(10)" query. If we set socketTimeout=1000, the query times out after 2 seconds. If we set socketTimeout=2000, the query times out after 4 seconds. We have observed this behaviour consistently. The driver documentation makes no mention of that behaviour. The attached simple program demonstrates the issue. It repeatedly times out after double the specified socketTimeout value, as printed to the console. How to repeat: package mysql; import java.sql.DriverManager; import java.sql.SQLException; public class TimeoutCase { static void main() { var url = "jdbc:mysql://localhost:3306/test?socketTimeout=1000"; var user = "root"; var password = "password"; for (int i = 0; i < 5; ++i) { try (var con = DriverManager.getConnection(url, user, password)) { System.out.println("Connected."); var stmt = con.createStatement(); var start = System.currentTimeMillis(); System.out.println("executing select sleep(10)"); try { stmt.executeQuery("select sleep(10)"); } catch (Throwable e) { var end = System.currentTimeMillis(); System.out.printf("timed out after %dms\n", (end - start)); } } catch (SQLException e) { e.printStackTrace(); } } } }