kestra-io/kestra · error · IllegalVariableEvaluationException
Found a null value in the ION file
Error message
Found a null value in the ION file
What it means
Thrown by `ionValueToString` while reading rows from an ION file backing a Loop task's URI-based `values` (see `readLoopValuesFromUri` / `readAndCountLoopValuesFromUri`). Each parsed record is converted to a string; if a record is `null` (an explicit null row in the ION stream), this fires. The ION file is fetched via `URIFetcher` and read with `FileSerde`.
Source
Thrown at core/src/main/java/io/kestra/core/runners/FlowableUtils.java:587
try (var is = new BufferedInputStream(URIFetcher.of(uri).fetch(runContext), FileSerde.BUFFER_SIZE)) {
List<String> result = new ArrayList<>(count);
long[] index = { 0 };
FileSerde.read(is, throwConsumer(record ->
{
if (index[0] >= offset && result.size() < count) {
result.add(ionValueToString(record));
}
index[0]++;
}));
return Pair.of(result, offset + result.size());
}
}
private static String ionValueToString(Object parsed) throws IllegalVariableEvaluationException {
return switch (parsed) {
case String s -> s;
case Number n -> n.toString();
case null -> throw new IllegalVariableEvaluationException("Found a null value in the ION file");
default -> serializeAsString(parsed);
};
}
}
View on GitHub (pinned to 823fada927)
Solutions
- Inspect and clean the upstream ION-producing task so it never writes a null record.
- Re-run the upstream task that generated the URI to regenerate a clean file.
- If the URI is a static file you control, edit it to remove null rows.
- Use an intermediate task to filter nulls before passing the URI to the Loop.
Example fix
# before — query may emit null rows into the ION file
tasks:
- id: data
type: io.kestra.plugin.jdbc.duckdb.Query
sql: "SELECT maybe_null_col FROM t"
- id: loop
type: io.kestra.plugin.core.flow.Loop
values: "{{ outputs.data.uri }}"
# after — coalesce nulls in SQL
sql: "SELECT COALESCE(maybe_null_col, '') AS maybe_null_col FROM t" Defensive patterns
Strategy: validation
Validate before calling
// Validate the ION file has no null rows before looping
try (var is = new BufferedInputStream(URIFetcher.of(uri).fetch(runContext), FileSerde.BUFFER_SIZE)) {
FileSerde.read(is, throwConsumer(rec -> {
if (rec == null) throw new IllegalVariableEvaluationException("ION file contains null row at URI " + uri);
}));
} Try / catch
try {
FlowableUtils.readLoopValuesFromUri(runContext, uri, offset, count);
} catch (IllegalVariableEvaluationException e) {
if (e.getMessage().equals("Found a null value in the ION file")) {
runContext.logger().error("ION source at {} has null rows; regenerate or clean it.", uri);
}
throw e;
} Prevention
- Ensure upstream SQL/query tasks COALESCE nullable columns before they serialize to ION.
- Re-run the producing task if the ION file is suspect.
- Validate ION files in a pre-task when the source is external.
When it happens
Trigger: A Loop/ForEach task whose `values` resolves to a URI (e.g. a Kestra internal storage URI or a `file://`/`http://` URI) pointing to an ION-encoded file, and that file contains a null record. ION is Kestra's row format for tabular outputs (queries, reads), so a null row can appear when a source has an empty line or a deserialized null object.
Common situations: Iterating over the rows of a SQL query / CSV read where a row serialized as null; a corrupted or partially-written ION file from a crashed upstream task; concatenating ION streams with a trailing null.
Related errors
- Scheme not supported: {}. Supported schemes are: {}
- Scheme not supported: {}
- Cannot process the URI %s: scheme not supported.
- Cannot process the URI %s: scheme not supported.
- Cannot process the URI %s: scheme not supported.
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/b8303c0252063f28.
Report an issue: GitHub.