apache/flink · error · IOException
Exactly one of LocalDate and LocalTime is null.
Error message
Exactly one of LocalDate and LocalTime is null.
What it means
LocalDateTimeSerializer splits a LocalDateTime into a LocalDate and a LocalTime and serializes each with its own singleton serializer. On deserialize it reconstructs the pair; the guard rejects the case where exactly one component is null, since that indicates inconsistent/null markers rather than a legitimate null LocalDateTime (both null).
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/LocalDateTimeSerializer.java:84
@Override
public void serialize(LocalDateTime record, DataOutputView target) throws IOException {
if (record == null) {
LocalDateSerializer.INSTANCE.serialize(null, target);
LocalTimeSerializer.INSTANCE.serialize(null, target);
} else {
LocalDateSerializer.INSTANCE.serialize(record.toLocalDate(), target);
LocalTimeSerializer.INSTANCE.serialize(record.toLocalTime(), target);
}
}
@Override
public LocalDateTime deserialize(DataInputView source) throws IOException {
LocalDate localDate = LocalDateSerializer.INSTANCE.deserialize(source);
LocalTime localTime = LocalTimeSerializer.INSTANCE.deserialize(source);
if (localDate == null && localTime == null) {
return null;
} else if (localDate == null || localTime == null) {
throw new IOException("Exactly one of LocalDate and LocalTime is null.");
} else {
return LocalDateTime.of(localDate, localTime);
}
}
@Override
public LocalDateTime deserialize(LocalDateTime reuse, DataInputView source) throws IOException {
return deserialize(source);
}
@Override
public void copy(DataInputView source, DataOutputView target) throws IOException {
LocalDateSerializer.INSTANCE.copy(source, target);
LocalTimeSerializer.INSTANCE.copy(source, target);
}
@Override
public TypeSerializerSnapshot<LocalDateTime> snapshotConfiguration() {View on GitHub (pinned to 2f3c205e92)
Solutions
- Verify the data was written with a compatible LocalDateTimeSerializer version (check serializer snapshot compatibility logs at restore).
- If you have a custom serialization path writing these components, ensure both the date and time halves are written or omitted together.
- Inspect the restore logs for a serializer schema mismatch (resolveSchemaCompatibility) between writer and reader.
- If the checkpoint data is corrupt, discard the savepoint and restart from a known-good state.
- Reproduce on a clean job to rule out stream truncation from network/disk errors.
Defensive patterns
Strategy: try-catch
Try / catch
try {
LocalDateTime value = LocalDateTimeSerializer.INSTANCE.deserialize(source);
} catch (IOException e) {
if (e.getMessage().contains("LocalDate and LocalTime is null")) {
log.error("Inconsistent LocalDateTime stream: one of date/time decoded as null; data is corrupt or serializer version mismatched");
}
throw e;
} Prevention
- Ensure writer and reader use the same LocalDateTimeSerializer version.
- Do not hand-write custom serialization for LocalDateTime components; let the framework handle it.
- Treat serializer schema warnings at restore as errors in CI.
- Keep checkpoints on durable storage and validate checksums to avoid corruption.
When it happens
Trigger: Deserializing a LocalDateTime from a stream where exactly one of the LocalDate/LocalTime components decoded as null while the other did not — typically stream corruption or a serializer mismatch.
Common situations: Corrupted checkpoint/savepoint bytes; a custom serialization path that wrote inconsistent null markers for the date and time halves; a version skew where LocalDateSerializer/LocalTimeSerializer null handling changed; partial write or truncation of the state stream.
Related errors
- Cannot deserialize and unwrap accumulators properly.
- Failed to serialize ExecutionPlan.
- Failed to deserialize coordination response
- Cannot deserialize and unwrap accumulators properly.
- Invalid version %d
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/555cf2dd50eb9f13.
Report an issue: GitHub.