apache/seatunnel · error · IllegalArgumentException

Binary custom filename requires a unique filename expression

Error message

Binary custom filename requires a unique filename expression when parallel subtasks are used. Please include <DEFAULT_FILE_NAME_EXPRESSION> or ${uuid} in file_name_expression.

What it means

When writing BINARY files with a custom filename in a parallel sink (multiple subtasks), each subtask would generate the same file name and overwrite each other. preCheckConfig guards this: if the custom file_name_expression lacks a per-subtask-unique token (<DEFAULT_FILE_NAME_EXPRESSION> or ${uuid}), it throws IllegalArgumentException.

Source

Thrown at seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sink/BaseFileSinkWriter.java:111

                String errorMsg =
                        String.format("Try to process these fileStates %s failed", fileSinkStates);
                throw new FileConnectorException(
                        CommonErrorCodeDeprecated.WRITER_OPERATION_FAILED, errorMsg, e);
            }
            writeStrategy.beginTransaction(fileSinkStates.get(0).getCheckpointId() + 1);
        } else {
            writeStrategy.beginTransaction(1L);
        }
        preCheckConfig(context);
    }

    private void preCheckConfig(SinkWriter.Context context) {
        if (writeStrategy.getFileSinkConfig().getFileFormat() == FileFormat.BINARY
                && writeStrategy.getFileSinkConfig().isCustomFilename()
                && context.getNumberOfParallelSubtasks() > 1
                && !hasParallelUniqueFilenameExpression(
                        writeStrategy.getFileSinkConfig().getFileNameExpression())) {
            throw new IllegalArgumentException(
                    "Binary custom filename requires a unique filename expression when parallel "
                            + "subtasks are used. Please include "
                            + DEFAULT_FILE_NAME_EXPRESSION
                            + " or ${"
                            + Constants.UUID
                            + "} in "
                            + FILE_NAME_EXPRESSION.key()
                            + ".");
        }
        if (writeStrategy.getFileSinkConfig().isSingleFileMode()
                && context.getNumberOfParallelSubtasks() > 1) {
            if (StringUtils.isNotEmpty(writeStrategy.getFileSinkConfig().getFileNameExpression())
                    && !writeStrategy
                            .getFileSinkConfig()
                            .getFileNameExpression()
                            .contains(DEFAULT_FILE_NAME_EXPRESSION)) {
                throw new IllegalArgumentException(
                        "Single file mode is not supported when "

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Include ${uuid} in file_name_expression (e.g. file_name_expression = "${uuid}_photo.jpg") to make each output unique
  2. Use <DEFAULT_FILE_NAME_EXPRESSION> in the expression so the default unique naming is embedded
  3. Keep sink parallelism at 1 if a fixed filename is truly required

Example fix

// before
sink {
  LocalFile {
    file_format = "binary"
    file_name_expression = "photo"
    parallelism = 2
  }
}
// after
sink {
  LocalFile {
    file_format = "binary"
    file_name_expression = "${uuid}_photo"
    parallelism = 2
  }
}
Defensive patterns

Strategy: validation

Validate before calling

if ("binary".equals(config.get("file_format")) && config.get("file_name_expression") != null
        && parallelism > 1
        && !config.get("file_name_expression").contains("${uuid}")
        && !config.get("file_name_expression").contains("<DEFAULT_FILE_NAME_EXPRESSION>")) {
    throw new IllegalArgumentException("binary custom filename must embed ${uuid} or <DEFAULT_FILE_NAME_EXPRESSION> at parallelism > 1");
}

Prevention

When it happens

Trigger: Configuring a file sink with file_format = binary, a custom file_name_expression without the default-expression or ${uuid} placeholder, while sink parallelism (context.getNumberOfParallelSubtasks()) is greater than 1.

Common situations: Copying a single-subtask binary sink config and scaling parallelism up; custom static filenames for images/binaries assuming one writer; forgetting that binary writes do not append transaction/part suffixes the way text formats do.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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