wp_get_attachment_image_src() does not return what I want

The following is entirely based on experiment over the last 15 minutes or so, so I wouldn’t call it canonical but …

wp_get_attachment_image_src() uses the image_downsize() function, which will attempt to find and return the image closest in size to the supplied size values. If you experiment with know image sizes (look at the actual images saved to wp-content/uploads) you will see what I mean. Despite the name, it will sometimes return larger images but the height and width components of the array should be set to the supplied values, or to some attempt at a scaled approximation (so it seems) if those values are wildly inaccurate. I can’t tell if that “scaling” is what is happening in your case but it might be and it seems likely.

Let me give an example. I have an image that saved as 150×150, 293×300, and full size. This…

var_dump(wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), array(20, 20)));

… returns an array with the 150×150 image and the sizes that I supplied– 20×20. However this…

var_dump(wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), array(200, 250)));

… returns the 150×150 image URL but with 200×204 for the sizes. That is not what I supplied. The size values have been altered by some algorithm. On further investigation it seem like image_constrain_size_for_editor is the more likely candidate.

You may also check to see if anything has applied a function to the image_downsize filter, as that will completely hijack the function.