As Sihua said, this shouldn't happen and indicates a bug. Did you only encounter this once or can you easily reproduce the problem?
in fact, from your code I can't see any possible that the MapState could be inconsistency with the timer, it's looks like a bug to me, because once the checkpoint's complete and you haven't query the state in a customer thread async, then the result of the checkpoint should be consistency. The only case, I can see where the timer could be inconsistency with state is when the task is shutting down, that case the backend maybe already closed but the timer failed to shutdown, so that the time callback function may access a closed backend. But it shouldn't be reason of your case. Maybe, could you please provide us more information, like what type of backend are you using? are you using the RocksDBBackend? and I think @Stefan may tell more about this, and please correct me if I'm incorrect.
You are right, there's no transactional guarantee on timers and state in processElement(). They may end up with inconsistency if your job was cancelled in the middle of processing an element.
To avoid the situation, the best programming practice is to always check if the state you're trying to get is null or not.