apache/seatunnel · error · SeaTunnelException

Failed to convert timestamp to SCN

Error message

Failed to convert timestamp to SCN

What it means

OracleConnectionUtils.timestampToScn wraps any SQLException from the TIMESTAMP_TO_SCN query in a SeaTunnelException 'Failed to convert timestamp to SCN'. This is thrown when the conversion SQL itself fails (as opposed to error 558's empty result). The original SQL error is logged and kept as the cause.

Solutions

  1. Read the wrapped SQLException/log lines for the exact ORA code
  2. Ensure the Oracle edition supports TIMESTAMP_TO_SCN (Enterprise with flashback); otherwise avoid startup.mode=timestamp
  3. Grant required privileges (SELECT_CATALOG_ROLE, EXECUTE on DBMS_FLASHBACK)
  4. Verify database is open and reachable, then retry

Example fix

// before (DBA)
-- missing privilege
// after
GRANT SELECT_CATALOG_ROLE TO seatunnel_user;
GRANT EXECUTE ON DBMS_FLASHBACK TO seatunnel_user;
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm the conversion function is available with the CDC user
SELECT TIMESTAMP_TO_SCN(SYSTIMESTAMP) FROM DUAL;

Try / catch

try {
    RedoLogOffset off = OracleConnectionUtils.timestampToScn(conn, ts, tz);
} catch (SeaTunnelException e) {
    Throwable root = e.getCause(); // SQLException with ORA code
    LOG.error("timestamp->SCN failed: ORA-{}", root instanceof SQLException ? ((SQLException) root).getErrorCode() : -1, e);
    throw e;
}

Prevention

When it happens

Trigger: SQLException during the timestamp→SCN query: missing privileges on the conversion function / V$ views, ORA-08185 (flashback not enabled / SCN differs from timestamp), ORA-00904 invalid identifier on older Oracle versions lacking TIMESTAMP_TO_SCN, or connection failure.

Common situations: Old Oracle editions (e.g., standard edition without flashback) lacking TIMESTAMP_TO_SCN; missing flashback/execute privileges; database in mount state; connectivity drops.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/c88a8502b48562c9. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-oracle/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/oracle/utils/OracleConnectionUtils.java:127

                    statement -> {
                        java.sql.Timestamp timestamp = new java.sql.Timestamp(timestampMs);
                        Calendar calendar =
                                Calendar.getInstance(TimeZone.getTimeZone(effectiveServerTimeZone));
                        statement.setTimestamp(1, timestamp, calendar);
                    },
                    rs -> {
                        if (rs.next()) {
                            final String scn = rs.getString(1);
                            LOG.info("Converted timestamp {} to SCN: {}", timestampMs, scn);
                            return new RedoLogOffset(Scn.valueOf(scn).longValue());
                        } else {
                            throw new SeaTunnelException(
                                    "Cannot convert timestamp to SCN. Make sure the specified timestamp is valid.");
                        }
                    });
        } catch (SQLException e) {
            LOG.error("Failed to convert timestamp to SCN", e);
            throw new SeaTunnelException("Failed to convert timestamp to SCN", e);
        }
    }

    public static List<TableId> listTables(
            JdbcConnection jdbcConnection, String database, RelationalTableFilters tableFilters)
            throws SQLException {
        final List<TableId> capturedTableIds = new ArrayList<>();

        Set<TableId> tableIdSet = new HashSet<>();
        String queryTablesSql =
                "SELECT OWNER ,TABLE_NAME,TABLESPACE_NAME FROM ALL_TABLES \n"
                        + "WHERE PARTITIONED = 'YES' OR (TABLESPACE_NAME IS NOT NULL AND TABLESPACE_NAME NOT IN ('SYSAUX'))";

        try {
            jdbcConnection.query(
                    queryTablesSql,
                    rs -> {
                        while (rs.next()) {

View on GitHub (pinned to cf67b549a7)