How to display future posts – modified query still yields 404

You are stepping on a query mine. It is easy to assume that:

  1. You can change query.
  2. Parameters are well defined.
  3. So by changing of parameters you can achieve desired results.

In reality there are plenty of query parameters, touching which leads into horrible dead ends. WordPress is engineered to query and show posts which are public. Any attempt to circumvent it comes with serious grief.

In your specific case this is what generated SQL query looks like (for draft post):

SELECT wp_posts.*
FROM wp_posts
WHERE 1=1 AND wp_posts.post_name="draft" 
    AND wp_posts.post_type="post" 
    AND ((
        wp_posts.post_status="publish" 
        OR wp_posts.post_status="future" 
        OR wp_posts.post_status="draft"
        ))
ORDER BY wp_posts.post_date DESC

Looks perfectly sane, doesn’t it? Well, except that post titled “Draft” doesn’t have post_name field set to anything.

It’s not “post is always a post” situation. It’s “posts are going to be subtly different and full of edge cases” situation.

Whenever you need more complex concept, such as “future” post, do not trust WP core to do it. It will have a hearty laugh, then ruin next three days of your life.

  1. Implement complex data as custom field data.
  2. Query it accordingly.