apache/flink · error · ValidationException
Option '%s.%s' must be a string with single character, but w
Error message
Option '%s.%s' must be a string with single character, but was: %s
What it means
Validation error from CsvCommons.validateCharacterVal(): a CSV character option ('csv.field-delimiter', 'csv.array-element-delimiter', 'csv.quote-character', 'csv.escape-character') is present but does not unescape to exactly one character. Note field-delimiter is Java-unescaped first, so '\t' is valid while '\t\n' or 'ab' is not; the message helpfully shows the raw configured value.
Source
Thrown at flink-formats/flink-csv/src/main/java/org/apache/flink/formats/csv/CsvCommons.java:92
/**
* Validates the option {@code option} value must be a Character.
*
* @param tableOptions the table options
* @param option the config option
* @param unescape whether to unescape the option value
*/
private static void validateCharacterVal(
ReadableConfig tableOptions, ConfigOption<String> option, boolean unescape) {
if (!tableOptions.getOptional(option).isPresent()) {
return;
}
final String value =
unescape
? StringEscapeUtils.unescapeJava(tableOptions.get(option))
: tableOptions.get(option);
if (value.length() != 1) {
throw new ValidationException(
String.format(
"Option '%s.%s' must be a string with single character, but was: %s",
IDENTIFIER, option.key(), tableOptions.get(option)));
}
}
public static Set<ConfigOption<?>> optionalOptions() {
Set<ConfigOption<?>> options = new HashSet<>();
options.add(FIELD_DELIMITER);
options.add(DISABLE_QUOTE_CHARACTER);
options.add(QUOTE_CHARACTER);
options.add(ALLOW_COMMENTS);
options.add(IGNORE_PARSE_ERRORS);
options.add(ARRAY_ELEMENT_DELIMITER);
options.add(ESCAPE_CHARACTER);
options.add(NULL_LITERAL);
options.add(WRITE_BIGDECIMAL_IN_SCIENTIFIC_NOTATION);
options.add(TRIM_SPACES);View on GitHub (pinned to 2f3c205e92)
Solutions
- Use exactly one character per option: ';' , '|', '\t', '\\' etc.
- If a multi-character separator is truly needed, switch formats (e.g. a custom format or preprocess the input) — CSV cannot express it.
- Double-check Java escape sequences: tab is '\t' (backslash-t in the SQL string), not the word 'tab'.
Example fix
-- before 'csv.field-delimiter' = '||' -- after 'csv.field-delimiter' = '|'
Defensive patterns
Strategy: validation
Validate before calling
// Validate before creating the table (mirrors Flink's check):
String v = options.get(key);
String unescaped = unescapeJava && v != null ? StringEscapeUtils.unescapeJava(v) : v;
if (v != null && (unescaped == null || unescaped.length() != 1)) {
throw new ValidationException(key + " must be a single character: " + v);
} Prevention
- Use single characters or Java escapes (\t, \\)
- Remember CSV has no multi-char delimiters — design ingestion accordingly
When it happens
Trigger: Setting 'csv.field-delimiter'='||' or ',,' (multi-char), or an escape that unescapes to multiple chars like '\\t'; also plain strings like 'tab' instead of '\t'. Triggered during format factory validation at table creation.
Common situations: Users trying multi-char delimiters (CSV spec forbids it) and expecting Flink to accept '||'; copy-paste of raw tab characters that editors expand; supplying the literal word 'semicolon' instead of ';'.
Related errors
- Format cannot define a quote character and disabled quote ch
- Delimiter must not be null
- Buffer size must be greater than length of delimiter.
- Field indices must not be smaller than zero.
- Missing type for included field {}.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/51a3b5fa22bb9745.
Report an issue: GitHub.