Image sizes and order of operations

wp_get_attachment_image_src will always return a URL to a file if the image exists in some size. If the size you ask for doesn’t exist then you get the URL for the full size image as uploaded. (This isn’t the “large” image size.)

So, for a valid image ID, your conditional if(wp_get_attachment_image_src($id, array($preferred_size, $preferred_size))) will always succeed, as wp_get_attachment_image_src always returns a URL, even if that URL isn’t the one you expect.

To fix it, I’d recommend that you don’t subvert the API and that you work with it instead.