How to filter the source URL of all images on every page

Is it expected behaviour that the wp_get_attachment_image_src filter only affects the featured image of a page, and not the images in the page content which have been added via the Add Media button?

Yes, that filter does not run on the image URLs after a post has been saved

If it’s not expected behaviour, then what might be causing this filter not to work on the other images on my site?

It is expected behaviour, this filter and others don’t run on content that has URLs saved in the database. It only impacts places were an attachment ID needs to be converted at runtime into a URL

If it is expected behaviour, then can you suggest an alternative function that would work on all of my images? Note that I’d prefer to use a proper WordPress filter to achieve this, rather than some kind of search and replace on the page contents.

No such filter exists, you will need to do some kind of search and replace on the page contents. Note that this will then require you to flush all caches, and will be incompatible with a lot of caching plugins and CDN caching systems such as Cloudflare if your goal is to cache bust images. It would be easier to give them new URLs.

Also you will need to adjust many filters and use various output buffers. E.g. you may think it enough to use the_content filter or an output buffer, but this would not fix REST API requests that some JS will use.