I have spent hours today on a maddening issue I was having with displaying a custom post type. Everything displayed beautifully, except the pagination simply would not work properly.

I have a page-template setup to display a "page of posts" (see Codex: Page of Posts) for a custom post type ('news').

I keep getting a 404 error when I click "Older Posts". I noticed a lot of other people have or had this problem.

Why is this happening? Here is my query & loop code:

    // Enable Pagination
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

    // The Args
    $args= array(
        'post_type' => 'news',
        'paged' => $paged,

    // The Query

    // The Loop
    while ( have_posts() ) : the_post(); ?>
// ...

3 Answers 3


I figured this problem out literally seconds before I posted the question, so I thought I would go ahead and post the answer here. I've noticed there is not a lot of consolidated help for this problem out there.

This will help you if your "Older Posts" or "Newer Posts" links give you a 404 error when trying to display custom posts on a page-template.

Here are the steps to solve the 404 issue (in most cases) if you are having it. Check after each to see if the problem goes away.

Step 1: Flush your permalinks

Go to settings => permalinks. Select default. Save. Test. Select your preference. Save. Test again.

Step 2: Check your query.

If flushing the permalinks doesn't fix the problem, double check your query. Use the Codex (see: Pages > page of posts). You need to define the $paged variable and use it in your query options.

Step 3: Make sure your posts_per_page does not conflict with the default.

There are some folks discussing this as a bug in the wordpress core. Whether or not that is the case, the posts_per_page => x option can cause issues with pagination if x is less than the default option.

A hack-ish solution to this issue is to set the default to 1 (settings > reading > "blogs show at most _ pages").

NOTE: At this point, I was STILL having the problem.. it was step 4 that finally fixed it for me.

Step 4: Make sure your page slug != your post_type.

In my case, I had post_type => 'news'. And the page I was using was www.mysite.com/news. This caused the conflict that ultimately goofed the pagination up. To fix, I changed my post_type to 'news-articles' and re-flushed the permalinks. The problem went away.

Hopefully this helps you if you experience the same issue. I have a feeling a lot of people fall into this snare - it's easy to do, and it's not super intuitive to figure out. (at least it wasn't for me).

  • Took me a while by trial and error, but Step 4 was my issue
    – Kevin
    Jul 3, 2012 at 3:31

About Step 3. Here is explanation why it happens: "Pagination is calculated before you get to the template file that runs query_posts. The proper way to alter posts_per_page conditionally is to use the pre_get_posts hook to modify the main query." https://wordpress.stackexchange.com/a/42063/17177 I found one implementation "pre_get_posts" that works for me http://uncommoncontent.com/2012/01/28/add-custom-post-types-to-the-loop:

if ( ! function_exists( 'ucc_add_cpts_to_pre_get_posts' ) ) {
    function ucc_add_cpts_to_pre_get_posts( $query ) {
        if ( $query->is_main_query() && ! is_post_type_archive() && ! is_singular() && ! is_404() ) {
        $my_post_type = get_query_var( 'post_type' );
            if ( empty( $my_post_type ) ) {
                $args = array(
                    'exclude_from_search' => false,
                    'public' => true,
                    '_builtin' => false
                $output = 'names';
                $operator = 'and';
                $post_types = get_post_types( $args, $output, $operator );

                // Or uncomment and edit to explicitly state which post types you want.
                // $post_types = array( 'event', 'location' );
                // Add 'link' and/or 'page' to array() if you want these included.
                // array( 'post', 'link', 'page' ), etc.
                $post_types = array_merge( $post_types, array( 'post' ) );
                $query->set('post_type', $post_types );

add_action( 'pre_get_posts', 'ucc_add_cpts_to_pre_get_posts' );

I have come with a simple solution, after hours of research :)

I put it all nicely on the blog for anyone who should come across this problem :)


Hope someone gets some joy out of it :)

Your Answer

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

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