apache/flink · error · TableException

Unsupported timestamp format '%s'. Validator should have che

Error message

Unsupported timestamp format '%s'. Validator should have checked that.

What it means

TableException from JsonFormatOptionsUtil.getTimestampFormat when the 'timestamp-format' option string is neither 'SQL' nor 'ISO-8601'. The message states the validator should have caught this: it only triggers when the config was assembled programmatically (or mutated) without running validateDecodingFormatOptions/validateEncodingFormatOptions first.

Source

Thrown at flink-formats/flink-json/src/main/java/org/apache/flink/formats/json/JsonFormatOptionsUtil.java:69

    // The handling mode of null key for map data
    public static final String JSON_MAP_NULL_KEY_MODE_FAIL = "FAIL";
    public static final String JSON_MAP_NULL_KEY_MODE_DROP = "DROP";
    public static final String JSON_MAP_NULL_KEY_MODE_LITERAL = "LITERAL";

    // --------------------------------------------------------------------------------------------
    // Utilities
    // --------------------------------------------------------------------------------------------

    public static TimestampFormat getTimestampFormat(ReadableConfig config) {
        String timestampFormat = config.get(TIMESTAMP_FORMAT);
        switch (timestampFormat) {
            case SQL:
                return TimestampFormat.SQL;
            case ISO_8601:
                return TimestampFormat.ISO_8601;
            default:
                throw new TableException(
                        String.format(
                                "Unsupported timestamp format '%s'. Validator should have checked that.",
                                timestampFormat));
        }
    }

    /**
     * Creates handling mode for null key map data.
     *
     * <p>See {@link #JSON_MAP_NULL_KEY_MODE_FAIL}, {@link #JSON_MAP_NULL_KEY_MODE_DROP}, and {@link
     * #JSON_MAP_NULL_KEY_MODE_LITERAL} for more information.
     */
    public static JsonFormatOptions.MapNullKeyMode getMapNullKeyMode(ReadableConfig config) {
        String mapNullKeyMode = config.get(MAP_NULL_KEY_MODE);
        switch (mapNullKeyMode.toUpperCase()) {
            case JSON_MAP_NULL_KEY_MODE_FAIL:
                return JsonFormatOptions.MapNullKeyMode.FAIL;
            case JSON_MAP_NULL_KEY_MODE_DROP:

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Use exactly 'SQL' or 'ISO-8601' (case-sensitive) for 'timestamp-format'
  2. Call JsonFormatOptionsUtil.validateDecodingFormatOptions/validateEncodingFormatOptions before getTimestampFormat in custom factories
  3. Prefer defining the table via DDL so the standard validator runs

Example fix

-- before
'timestamp-format' = 'sql'

-- after
'timestamp-format' = 'SQL'
Defensive patterns

Strategy: validation

Validate before calling

Set<String> ok = new HashSet<>(Arrays.asList("SQL", "ISO-8601"));
if (!ok.contains(config.get(JsonFormatOptions.TIMESTAMP_FORMAT))) {
    throw new ValidationException("timestamp-format must be SQL or ISO-8601");
}

Prevention

When it happens

Trigger: Building a ReadableConfig by hand and calling getTimestampFormat directly; a custom format factory skipping validation; case-sensitivity mismatch ('sql' lowercase, since the switch is exact-match on SQL/ISO_8601 constants).

Common situations: Custom DynamicTableFactory reusing JsonFormatOptionsUtil without the validate step; option set via Configuration.set with an unchecked string; downstream code bypassing DDL validation.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/da43d68ca26f0f17. Report an issue: GitHub.