alibaba/druid · error · SQLException

validationQuery didn't return a row

Error message

validationQuery didn't return a row

What it means

Thrown during connection validation when a configured validationQuery is executed via ValidConnectionCheckerAdapter.execValidQuery but the query returns no rows. Druid uses the validation query (e.g. SELECT 1) to confirm a connection is alive; a query that returns zero rows is treated as proof the connection is unusable. This guard runs on testWhileIdle, testOnBorrow, testOnReturn, and keepAlive paths.

Source

Thrown at core/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java:1490

            return;
        }

        if (null != query) {
            boolean valid;
            try {
                valid = ValidConnectionCheckerAdapter.execValidQuery(conn, query, validationQueryTimeout);
            } catch (SQLException ex) {
                throw ex;
            } catch (Exception ex) {
                throw new SQLException("validationQuery failed", ex);
            } finally {
                if (conn instanceof ConnectionProxyImpl) {
                    ((ConnectionProxyImpl) conn).setLastValidateTimeMillis(System.currentTimeMillis());
                }
            }

            if (!valid) {
                throw new SQLException("validationQuery didn't return a row");
            }

            if (onFatalError) {
                lock.lock();
                try {
                    if (onFatalError) {
                        onFatalError = false;
                    }
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    /**
     * @deprecated
     */

View on GitHub (pinned to fa8dc99126)

Solutions

  1. Set validationQuery to a statement guaranteed to return exactly one row for your database (MySQL: 'SELECT 1', Oracle: 'SELECT 1 FROM DUAL', PostgreSQL: 'SELECT 1').
  2. Verify the DB user has SELECT privileges on whatever the validationQuery references.
  3. Prefer using a ValidConnectionChecker (Druid auto-selects one per dbType) by leaving validationQuery default rather than overriding it with a fragile custom query.
  4. If using testWhileIdle/keepAlive, confirm the validation query works by running it manually in the same session context.

Example fix

// before
dataSource.setValidationQuery("SELECT 1 FROM app_config WHERE flag='on'");
// after
dataSource.setValidationQuery("SELECT 1");
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm the validation query returns a row in your DB before assigning it
String vq = dataSource.getValidationQuery();
try (Connection c = dataSource.getDriver().connect(dataSource.getUrl(), dataSource.getConnectProperties());
     Statement s = c.createStatement();
     ResultSet rs = s.executeQuery(vq)) {
    if (!rs.next()) {
        throw new IllegalStateException("validationQuery returns no rows: " + vq);
    }
}

Try / catch

try {
    conn = dataSource.getConnection();
} catch (SQLException e) {
    if (e.getMessage() != null && e.getMessage().contains("validationQuery didn't return a row")) {
        LOG.error("validationQuery misconfigured; check " + dataSource.getValidationQuery(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: validateConnection(conn) is called with a non-null query, execValidQuery returns false (empty ResultSet), and the !valid branch at line 1489 fires. Happens when validationQuery is set to something that conditionally returns no rows, or when the DB session is in a state where the query yields nothing.

Common situations: A validationQuery like 'SELECT 1 FROM dual WHERE 1=0' that deliberately returns no rows; a query referencing a table/object the connecting user lacks privileges on; a stale connection whose session state makes the validation query return empty; custom validation queries ported from another DB dialect.

Related errors


AI-assisted analysis of alibaba/druid@fa8dc99126 (2026-08-14). Data as JSON: /api/errors/318d00d425d03694. Report an issue: GitHub.