{"record":{"id":"0d9d26adb27c00d8","repo":"alibaba/druid","slug":"validateconnection-connection-closed","errorCode":null,"errorMessage":"validateConnection: connection closed","messagePattern":"validateConnection: connection closed","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"info","filePath":"core/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java","lineNumber":1437,"sourceCode":"\n        String[] filterArray = filters.split(\"\\\\,\");\n\n        for (String item : filterArray) {\n            FilterManager.loadFilter(this.filters, item.trim());\n        }\n    }\n\n    public void clearFilters() {\n        if (!isClearFiltersEnable()) {\n            return;\n        }\n        this.filters.clear();\n    }\n\n    public void validateConnection(Connection conn) throws SQLException {\n        String query = getValidationQuery();\n        if (conn.isClosed()) {\n            throw new SQLException(\"validateConnection: connection closed\");\n        }\n\n        if (validConnectionChecker != null) {\n            boolean result;\n            Exception error = null;\n            try {\n                result = validConnectionChecker.isValidConnection(conn, validationQuery, validationQueryTimeout);\n\n                if (conn instanceof ConnectionProxyImpl) {\n                    ((ConnectionProxyImpl) conn).setLastValidateTimeMillis(System.currentTimeMillis());\n                }\n                if (result && onFatalError) {\n                    lock.lock();\n                    try {\n                        if (onFatalError) {\n                            onFatalError = false;\n                        }\n                    } finally {","sourceCodeStart":1419,"sourceCodeEnd":1455,"githubUrl":"https://github.com/alibaba/druid/blob/fa8dc9912637a2f729eef9f55356621fec18d40e/core/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java#L1419-L1455","documentation":"validateConnection(Connection) probes conn.isClosed() before running the validation query/validConnectionChecker and throws SQLException(\"validateConnection: connection closed\") when the driver reports the connection as already closed. This is an operational signal, not a configuration defect: the physical connection died (server-side timeout, network drop, DB restart, manual close) and must be discarded by the pool.","triggerScenarios":"Druid's keep-alive/validate task calls validateConnection on a pooled connection whose driver reports isClosed()==true; or a user calls validateConnection directly on a closed connection.","commonSituations":"Database or network restarted idle connections; an external firewall/LB reaped idle TCP connections; the server's wait_timeout is shorter than Druid's eviction interval; a connection was explicitly closed elsewhere.","solutions":["Tune maxEvictableIdleTimeMillis / keepAlive to be shorter than the DB/server idle timeout so connections are evicted/kept-alive before the server closes them.","Ensure keepAliveBetweenTimeMillis and validationQuery are configured so dead connections are detected and replaced.","If seen repeatedly in logs, investigate network/firewall idle reaping or DB wait_timeout.","This exception is normally handled internally by the pool; no app code change is needed unless it surfaces to callers."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight check before relying on a connection from the pool:\n// if (conn == null || conn.isClosed()) { request a fresh connection / let the pool replace it }\n// Configure the pool so this is rare:\n// ds.setMaxEvictableIdleTimeMillis(< db wait_timeout); ds.setKeepAlive(true);","typeGuard":null,"tryCatchPattern":"// This is normally handled inside the pool. If you call validateConnection directly:\ntry {\n    ds.validateConnection(conn);\n} catch (SQLException e) {\n    if (\"validateConnection: connection closed\".equals(e.getMessage())) {\n        // discard conn, obtain a new one from the pool\n    }\n}","preventionTips":["Set maxEvictableIdleTimeMillis shorter than the DB server's idle timeout (e.g. MySQL wait_timeout).","Enable keepAlive and configure keepAliveBetweenTimeMillis to keep idle connections viable.","Investigate recurring occurrences as network/firewall idle reaping or DB restarts."],"tags":["datasource","connection-validation","pool-operation","network"],"backgroundTag":null,"analyzedSha":"fa8dc9912637a2f729eef9f55356621fec18d40e","analyzedAt":"2026-08-14T04:55:06.789Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}