How to resolve KeyError 'val_mean_absolute_error' Keras 2.3.1 and TensorFlow 2.0 From Chollet Deep Learning with Python
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
This KeyError happens when your code tries to read a metric from history.history using a name that is not actually present. In older Keras and early TensorFlow 2 combinations, metric key names changed depending on how the metric was specified, so code copied from a book or notebook often asked for val_mean_absolute_error while the training history actually stored something like val_mae.
Why the Error Happens
When you call model.fit(...), Keras returns a History object. Its history field is a dictionary of metric names to recorded values.
Example:
If your code later does this:
but that key is not in the dictionary, Python raises:
So the immediate fix is not guesswork. It is to inspect the keys that actually exist.
Inspect the Available History Keys First
A minimal example:
Typical output may include keys such as:
In that case, the correct key is val_mae, not val_mean_absolute_error.
Use the Key That Matches Your Compile Call
If you compiled like this:
then your plotting code should use:
If you compiled like this:
then the history key is more likely to be:
That is the core rule: metric names in the history dictionary come from how the metric was registered.
A Safer Plotting Pattern
Instead of hardcoding one metric name from memory, inspect the available keys and choose the correct one:
This makes notebooks and teaching examples more resilient across Keras versions.
Validation Metrics Exist Only If You Logged Validation Data
Another reason the key can be missing is that no validation metrics were recorded at all. If you never passed validation data or a validation split, there will be no val_... entries.
For example, this will not create val_* keys:
But this will:
So before worrying about naming differences, make sure validation metrics were actually requested during training.
Why Book Code Sometimes Breaks
Examples from books and older tutorials often reflect one exact package combination. Later environments can still train the model successfully while changing the metric key names slightly.
Common variations include:
- '
maeversusmean_absolute_error' - '
accversusaccuracy' - '
val_maeversusval_mean_absolute_error'
This is why printing history.history.keys() is usually the first debugging step for any Keras plotting error.
A Clean Modern Pattern
A robust training and plotting snippet looks like this:
That keeps the example compatible with the actual history keys rather than assuming one exact metric name.
Common Pitfalls
The biggest pitfall is hardcoding val_mean_absolute_error without checking what keys history.history actually contains.
Another common issue is compiling with a shorthand metric such as "mae" and then expecting the long-form metric name in the history dictionary.
People also often forget to pass validation data, then wonder why every val_* key is missing. No validation input means no validation metrics.
Finally, do not debug this as if the model is failing to train. In most cases the training worked fine. The error is in the code that reads the training history afterward.
Summary
- The error means the requested metric key is not present in
history.history. - Print
history.history.keys()first to see the actual metric names. - '
val_maeandval_mean_absolute_errorare both plausible depending on how the metric was defined.' - Validation keys exist only if you used validation data or
validation_split. - The safest fix is to select the metric name based on the keys actually recorded.

