Turns out this was caused by the following custom theme filter in functions.php. Commenting out fixed the problem.
function image_alt_tags($content) {
global $post;
preg_match_all('/<img (.*?)\/>/', $content, $images);
if (!is_null($images)) {
foreach($images[1] as $index => $value) {
if (!preg_match('/alt=/', $value)) {
$new_img = str_replace('<img', '<img alt="' . get_the_title() . '"', $images[0][$index]);
$content = str_replace($images[0][$index], $new_img, $content);
}
}
}
return $content;
}
add_filter('the_content', 'image_alt_tags', 99999);
add_filter('post_thumbnail_html', 'thumbnail_filter', 99, 5);
function thumbnail_filter($html, $post_id, $post_thumbnail_id, $size, $attr) {
// you can alter the resulted HTML here
$html = preg_replace(array('/alt=\".*?\"https://wordpress.stackexchange.com/", '/title=\".*?\"https://wordpress.stackexchange.com/"), '', $html);
return $html;
}