apache/seatunnel · error · CatalogException

Truncate table failed

Error message

Truncate table failed

What it means

ClickhouseCatalog.truncateTable deletes all rows of the target table via the proxy client when the table exists. Any failure (connection error, insufficient rights, unsupported table engine) is wrapped in a CatalogException with the message 'Truncate table failed'. Unlike other methods, the message omits the table name, so the cause chain carries the details.

Source

Thrown at seatunnel-connectors-v2/connector-clickhouse/src/main/java/org/apache/seatunnel/connectors/seatunnel/clickhouse/catalog/ClickhouseCatalog.java:169

                table.getComment(),
                table.getTableSchema());
    }

    @Override
    public void dropTable(TablePath tablePath, boolean ignoreIfNotExists)
            throws TableNotExistException, CatalogException {
        proxy.dropTable(tablePath, ignoreIfNotExists);
    }

    @Override
    public void truncateTable(TablePath tablePath, boolean ignoreIfNotExists)
            throws TableNotExistException, CatalogException {
        try {
            if (tableExists(tablePath)) {
                proxy.truncateTable(tablePath, ignoreIfNotExists);
            }
        } catch (Exception e) {
            throw new CatalogException("Truncate table failed", e);
        }
    }

    @Override
    public void executeSql(TablePath tablePath, String sql) {
        try {
            proxy.executeSql(sql);
        } catch (Exception e) {
            throw new CatalogException(String.format("Failed EXECUTE SQL in catalog %s", sql), e);
        }
    }

    @Override
    public boolean isExistsData(TablePath tablePath) {
        try {
            return proxy.isExistsData(tablePath.getFullName());
        } catch (ExecutionException | InterruptedException e) {
            throw new RuntimeException(e);

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check the root cause in the wrapped exception ('Caused by') for the actual ClickHouse error
  2. Grant the ClickHouse user the privileges needed to truncate the table (ALTER/TRUNCATE) or use an admin account
  3. If the engine does not support TRUNCATE, drop and recreate the table via executeSql instead
  4. Verify the table still exists and is writable at execution time; handle race with tableExists

Example fix

// before
catalog.truncateTable(tablePath, true);
// after
try {
    catalog.truncateTable(tablePath, true);
} catch (CatalogException e) {
    logger.warn("Truncate failed for {}: {}", tablePath.getFullName(), e.getCause());
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!catalog.tableExists(tablePath)) {
    return; // nothing to truncate
}
// confirm user can truncate
catalog.executeSql(tablePath, "SELECT count() FROM system.grants WHERE user = currentUser() AND privilege ILIKE '%ALTER%'");

Try / catch

try {
    catalog.truncateTable(tablePath, ignoreIfNotExists);
} catch (CatalogException e) {
    Throwable cause = e.getCause();
    logger.error("Truncate table failed: {}", cause == null ? e.getMessage() : cause.getMessage());
    if (cause instanceof java.net.ConnectException) {
        // retry transient failure
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling truncateTable(tablePath, ignoreIfNotExists) when ClickHouse rejects the TRUNCATE statement: read-only user, non-truncatable engine (e.g. Distributed without support, Memory quirks), or the proxy call itself fails mid-request.

Common situations: User lacking ALTER/TRUNCATE privilege on the table; truncating a Distributed table where underlying local tables reject the operation; transient network failure to ClickHouse; table exists per check but is dropped before truncate executes.

Related errors


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