apache/seatunnel · error · FileConnectorException
COMMON_ILLEGAL_ARGUMENT
COMMON_ILLEGAL_ARGUMENT
Error message
file_name_expression must contains <TRANSACTION_EXPRESSION> when is_enable_transaction is true
What it means
FileSinkConfig's constructor validates that when is_enable_transaction is true, the file_name_expression must contain the <TRANSACTION_EXPRESSION> placeholder. Transaction mode needs a unique suffix per attempt so uncommitted/aborted files can be distinguished and cleaned up. Throws FileConnectorException with CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT.
Solutions
- Add the placeholder: file_name_expression = "out_<TRANSACTION_EXPRESSION>".
- Or set is_enable_transaction = false if exactly-once file commit is not needed.
- Use the default file_name_expression, which already contains the transaction expression.
Example fix
// before
file_name_expression = "data_${now}"
is_enable_transaction = true
// after
file_name_expression = "data_${now}_<TRANSACTION_EXPRESSION>"
is_enable_transaction = true Defensive patterns
Strategy: validation
Validate before calling
if (config.isEnableTransaction && (config.fileNameExpression == null || !config.fileNameExpression.contains("<TRANSACTION_EXPRESSION>"))) {
throw new IllegalArgumentException("file_name_expression must contain <TRANSACTION_EXPRESSION> when is_enable_transaction=true");
} Try / catch
try {
sink.open();
} catch (FileConnectorException e) {
if (e.getHttpCodeOrCode() == CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT) {
// fix file_name_expression and resubmit
}
throw e;
} Prevention
- Use file_name_expression templates that always include <TRANSACTION_EXPRESSION> when transactions are on.
- Keep transaction and filename options in the same config block to review together.
- Catch FileConnectorException at job submission to fail fast with a clear message.
When it happens
Trigger: is_enable_transaction = true while file_name_expression is unset or set without '<TRANSACTION_EXPRESSION>' (e.g. 'out_${now}').
Common situations: Users enabling transactional writes for exactly-once semantics but writing a custom filename that drops the placeholder; templates copied from non-transactional examples.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- BINARY_FILE_PART_ORDER_ERROR
- CanalJson file does not support this compress type
- Csv file does not support this compress type
- DebeziumJson file does not support this compress type
- Failed to finish the JDBC source read transaction. Closing…
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/14663cd5213c080a.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sink/config/FileSinkConfig.java:137
if (pluginConfig.getOptional(FileBaseSinkOptions.PARTITION_DIR_EXPRESSION).isPresent()
&& !StringUtils.isBlank(
pluginConfig.get(FileBaseSinkOptions.PARTITION_DIR_EXPRESSION))) {
this.partitionDirExpression =
pluginConfig.get(FileBaseSinkOptions.PARTITION_DIR_EXPRESSION);
}
this.isPartitionFieldWriteInFile =
pluginConfig.get(FileBaseSinkOptions.IS_PARTITION_FIELD_WRITE_IN_FILE);
this.tmpPath = pluginConfig.get(FileBaseSinkOptions.TMP_PATH);
this.fileNameTimeFormat = pluginConfig.get(FileBaseSinkOptions.FILENAME_TIME_FORMAT);
this.isEnableTransaction = pluginConfig.get(FileBaseSinkOptions.IS_ENABLE_TRANSACTION);
this.encoding = pluginConfig.get(FileBaseSinkOptions.ENCODING);
if (this.isEnableTransaction
&& !this.fileNameExpression.contains(FileBaseSinkOptions.TRANSACTION_EXPRESSION)) {
throw new FileConnectorException(
CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT,
"file_name_expression must contains "
+ FileBaseSinkOptions.TRANSACTION_EXPRESSION
+ " when is_enable_transaction is true");
}
// check partition field must in seaTunnelRowTypeInfo
if (!CollectionUtils.isEmpty(this.partitionFieldList)
&& (CollectionUtils.isEmpty(this.sinkColumnList)
|| !new HashSet<>(this.sinkColumnList)
.containsAll(this.partitionFieldList))) {
throw new FileConnectorException(
CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT,
"partition fields must in sink columns");
}
if (!CollectionUtils.isEmpty(this.partitionFieldList) && !isPartitionFieldWriteInFile) {
if (!this.sinkColumnList.removeAll(this.partitionFieldList)) {View on GitHub (pinned to cf67b549a7)