Underfitting is the quieter failure, and it often goes unnoticed.
The model is bad, and it is bad everywhere, including on training data.
Overfitting at least looks impressive somewhere first.
The usual cause is a model too simple for the pattern in front of it.
A straight line will never follow a curve, however long you train it.
Another cause is features that simply do not carry the information.
No model predicts house price from the colour of the front door.
Too much regularization does it too, by forcing the model to stay simple.
Stopping training too early gives you the same result.
The fix is more capacity, better features, or less restriction.
Diagnose it by looking at the training error first.
If the model cannot fit data it has already seen, more data will not help.
That is the key difference from overfitting, where more data usually does help.
Try a deliberately oversized model as a test.
If that also fails, your problem is the features, not the algorithm.