apache/shardingsphere · critical · DatetimeLoadingException

400

400

Error message

Load datetime from database failed.

What it means

DatabaseTimestampService loads the system time by executing a dialect-specific SQL statement (from the TimestampLoadingSQLProvider SPI) against a configured backend datasource. If that query fails — connection failure, wrong storage type resolution, or a result row that cannot be cast to Timestamp — it wraps the SQLException in DatetimeLoadingException (error code 400).

Source

Thrown at kernel/time-service/type/database/src/main/java/org/apache/shardingsphere/timeservice/type/database/DatabaseTimestampService.java:60

public final class DatabaseTimestampService implements TimestampService {
    
    private DataSource dataSource;
    
    private DatabaseType storageType;
    
    @Override
    public void init(final Properties props) {
        dataSource = DataSourcePoolCreator.create(new YamlDataSourceConfigurationSwapper().swapToDataSourcePoolProperties(
                props.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey().toString(), Entry::getValue))));
        storageType = DatabaseTypeEngine.getStorageType(dataSource);
    }
    
    @Override
    public Timestamp getTimestamp() {
        try {
            return loadDatetime(dataSource, DatabaseTypedSPILoader.getService(TimestampLoadingSQLProvider.class, storageType).getTimestampLoadingSQL());
        } catch (final SQLException ex) {
            throw new DatetimeLoadingException(ex);
        }
    }
    
    private Timestamp loadDatetime(final DataSource dataSource, final String datetimeLoadingSQL) throws SQLException {
        try (
                Connection connection = dataSource.getConnection();
                PreparedStatement preparedStatement = connection.prepareStatement(datetimeLoadingSQL)) {
            try (ResultSet resultSet = preparedStatement.executeQuery()) {
                resultSet.next();
                return (Timestamp) resultSet.getObject(1);
            }
        }
    }
    
    @Override
    public String getType() {
        return "Database";
    }

View on GitHub (pinned to e952770a21)

Solutions

  1. Verify the configured time-service datasource URL, credentials, and reachability with a plain JDBC client from the same host.
  2. Check that the resolved storage type has a TimestampLoadingSQLProvider SPI on the classpath and that its SQL runs manually against the backend.
  3. Grant the backend user permission to execute the timestamp-loading SQL and ensure it returns exactly one Timestamp value.
  4. If the environment cannot host a time DB, switch the time service to another type (e.g. system clock) via configuration.
  5. Inspect the cause chain of DatetimeLoadingException — it carries the original SQLException with the driver's real error.

Example fix

// before (server.yaml fragment with broken url)
time-service:
  type: Database
  props:
    url: jdbc:mysql://127.0.0.1:3307/timestamp_db   # wrong port
    username: root
    password: root

// after
time-service:
  type: Database
  props:
    url: jdbc:mysql://127.0.0.1:3306/timestamp_db   # verified reachable
    username: root
    password: root
Defensive patterns

Strategy: retry

Validate before calling

// before starting: verify the time-service datasource is reachable
try (Connection c = DriverManager.getTimeServiceConnection == null ? null : DriverManager.getConnection(url, user, pwd);
     Statement s = c.createStatement(); ResultSet r = s.executeQuery("SELECT CURRENT_TIMESTAMP")) {
    r.next();
} // mirrored pre-flight check for the configured url/user/password

Try / catch

try { Timestamp ts = timestampService.getTimestamp(); } catch (final DatetimeLoadingException ex) { SQLException cause = (SQLException) ex.getCause(); /* inspect cause: connectivity, permission, or SQL provider */ }

Prevention

When it happens

Trigger: Configuring the time service with type=database (props: url/username/password or jdbc-url style keys), then starting the proxy/JDBC instance so getTimestamp() runs the loading SQL and hits an SQLException: bad URL, unreachable DB, missing SPI provider for the resolved storage type, or a query returning a non-Timestamp/empty result.

Common situations: Typos in the time-service datasource URL; the backend user lacking SELECT permission on the timestamp source (e.g. MySQL's NOW() query or pg_catalog); a database type with no TimestampLoadingSQLProvider registered; network/firewall blocks between proxy and the time database; the selected row's first column not being a timestamp.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/820ed0ac7e3629fc. Report an issue: GitHub.