apache/seatunnel · warning · ClickhouseConnectorException

Unable to delete directory " + localFileDir

Error message

Unable to delete directory " + localFileDir

What it means

clearLocalFileDirectory removes the temporary local file directory with commons-io FileUtils.deleteDirectory after flushing. If an IOException occurs during deletion, it wraps it in a ClickhouseConnectorException with DELETE_DIRECTORY_FIELD and the message "Unable to delete directory <dir>".

Source

Thrown at seatunnel-connectors-v2/connector-clickhouse/src/main/java/org/apache/seatunnel/connectors/seatunnel/clickhouse/sink/file/ClickhouseFileSinkWriter.java:414

        fileTransfer.init();
        int randomPath = threadLocalRandom.nextInt(shardLocalDataPaths.get(shard).size());
        fileTransfer.transferAndChown(
                clickhouseLocalFiles, shardLocalDataPaths.get(shard).get(randomPath) + "detached/");
        fileTransfer.close();
    }

    private void clearLocalFileDirectory(List<String> clickhouseLocalFiles) {
        String clickhouseLocalFile = clickhouseLocalFiles.get(0);
        String localFileDir =
                clickhouseLocalFile.substring(
                        0, readerOption.getFileTempPath().length() + UUID_LENGTH + 1);
        try {
            File file = new File(localFileDir);
            if (file.exists()) {
                FileUtils.deleteDirectory(file);
            }
        } catch (IOException e) {
            throw new ClickhouseConnectorException(
                    ClickhouseConnectorErrorCode.DELETE_DIRECTORY_FIELD,
                    "Unable to delete directory " + localFileDir,
                    e);
        }
    }

    private String adjustClickhouseDDL() {
        String createTableDDL =
                clickhouseTable
                        .getCreateTableDDL()
                        .replace(clickhouseTable.getDatabase() + ".", "")
                        .replaceAll("`", "");
        if (createTableDDL.contains(CLICKHOUSE_SETTINGS_KEY)) {
            List<String> filters =
                    Arrays.stream(CLICKHOUSE_DDL_SETTING_FILTER.split(","))
                            .collect(Collectors.toList());
            int p = createTableDDL.indexOf(CLICKHOUSE_SETTINGS_KEY);
            String filteredSetting =

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check for running clickhouse-local processes holding files open in the directory and kill them
  2. Grant the worker user write permission on the directory and its contents
  3. Manually delete the leftover directory if it blocks subsequent runs
  4. Avoid putting localFileDir on flaky network filesystems
Defensive patterns

Strategy: try-catch

Try / catch

try {
    // flush
} catch (ClickhouseConnectorException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Unable to delete directory")) {
        // schedule manual cleanup of localFileDir; check for file locks
    }
}

Prevention

When it happens

Trigger: prepareCommit's finally-block cleanup when the OS refuses to delete the directory — files locked by another process, permission denied on files inside the directory, or directory still in use.

Common situations: A leftover clickhouse-local process still holds file handles in the directory; the worker user lacks write permission on parent dir or contained files; NFS/network filesystem mount issues.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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