Within the loop, for a post (of custom post type) which does not have a featured image:

  1. has_post_thumbnail() (with or without specified $post->ID) is returning true, while
  2. get_the_post_thumbnail(), also with our without the $post->ID returns an empty string.

The loop:

$args = array(
'post_type' => 'customs', 
'post_status' => 'publish',
'fields' => 'id',
'posts_per_page' => -1
$query = new WP_Query($args);
while ( $query->have_posts() ) : $query->the_post(); 
  the_title(); // as expected
  the_excerpt(); // as expected

The CPT is defined as follows:

    $name          = 'Custom';
    $singular_name = 'Custom';
    $slug          = 'custom';
    $menu_icon     = 'universal-access';

    // Declare args and apply filters
    $args = array(
        'labels' => array(
            'name' => $name,
            'singular_name' => $singular_name,
            'add_new' => __( 'Add New', 'total' ),
            'add_new_item' => __( 'Add New Item', 'total' ),
            'edit_item' => __( 'Edit Item', 'total' ),
            'new_item' => __( 'Add New Custom Item', 'total' ),
            'view_item' => __( 'View Item', 'total' ),
            'search_items' => __( 'Search Items', 'total' ),
            'not_found' => __( 'No Items Found', 'total' ),
            'not_found_in_trash' => __( 'No Items Found In Trash', 'total' )
        'public' => true,
        'supports' => array(
            // 'comments',
        'capability_type' => 'post',
        'rewrite' => array( 'slug' => $slug, 'with_front' => false ),
        'has_archive' => true,
        'menu_icon' => 'dashicons-'. $menu_icon,
        'menu_position' => 20,

    // Register the post type
    register_post_type( 'customs', $args );


While I can get desired outcome with:

if (get_the_post_thumbnail() !== ''):
  // display the thumbnail
  // some other option

I'm confident that's not the solution. Where else can I poke around for what's causing this unexpected and undesired result?

  • 1
    Actually, that is one of the better solutions. I've noticed this behavior before, and consider it a bug or misleading design for has_post_thumbnail().Was very vexing for me when I was developing a plug-in, but I've never had to deal with it in relation to a custom post type. It most commonly crops up with posts that have been restored or imported, but have lot their thumbnails. Would take a little investigation to determine what exactly is happening in the new custom post object, To be safe, I test for an actual ( ! empty) value.
    – CK MacLeod
    Commented Apr 19, 2017 at 4:14

1 Answer 1


I have tested on my test site the exact code you have shared above but it is working fine for me without any issue.

It seems you are facing the issue as described on this page WordPress has_post_thumbnail() not working – How to fix the phantom featured image issue that you might encounter, especially if you’re working with migrated content, or for some reason your database has weirdness.

So instead of has_post_thumbnail() you can use code like following to check existence of thumbnail attached to post.

$img_url = wp_get_attachment_url( get_post_thumbnail_id() );

if  ( ! empty( $img_url ) ) {

 // Do what you want to do if featured image is set to post
  • +1 but not sure if this is a true problem needed to be solved. the problem here is that of DB/file system corruption, and it is a deep rabbit hole if you want to fight all of the possible aspects of such a thing. Commented Apr 19, 2017 at 5:23
  • @MarkKaplun I can confirm that it is only with imported posts that this is a problem.
    – MikeiLL
    Commented Apr 19, 2017 at 15:05
  • I ran this little benchmarking test stackoverflow.com/a/1202746/2223106 loping three times for three posts. wp_get_attachment_url( get_post_thumbnail_id() ) was faster the first time, slower the second time and matching around 0.0 on subsequent runs. get_the_post_thumbnail(); may have been a tiny bit faster for two of more posts, although slower on the first.
    – MikeiLL
    Commented Apr 19, 2017 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.