Index: wp-includes/class-wp.php
===================================================================
--- wp-includes/class-wp.php	(revision 17567)
+++ wp-includes/class-wp.php	(working copy)
@@ -25,7 +25,7 @@
 	 * @since 2.0.0
 	 * @var array
 	 */
-	var $private_query_vars = array('offset', 'posts_per_page', 'posts_per_archive_page', 'showposts', 'nopaging', 'post_type', 'post_status', 'category__in', 'category__not_in', 'category__and', 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'tag_id', 'post_mime_type', 'perm', 'comments_per_page', 'post__in', 'post__not_in');
+	var $private_query_vars = array('offset', 'posts_per_page', 'posts_per_archive_page', 'showposts', 'nopaging', 'post_status', 'category__in', 'category__not_in', 'category__and', 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'tag_id', 'post_mime_type', 'perm', 'comments_per_page', 'post__in', 'post__not_in');
 
 	/**
 	 * Extra query variables set by the user.
@@ -277,15 +277,29 @@
 			if ( $t->query_var && isset( $this->query_vars[$t->query_var] ) )
 				$this->query_vars[$t->query_var] = str_replace( ' ', '+', $this->query_vars[$t->query_var] );
 
-		// Limit publicly queried post_types to those that are publicly_queryable
-		if ( isset( $this->query_vars['post_type']) ) {
-			$queryable_post_types = get_post_types( array('publicly_queryable' => true) );
-			if ( ! is_array( $this->query_vars['post_type'] ) ) {
-				if ( ! in_array( $this->query_vars['post_type'], $queryable_post_types ) )
-					unset( $this->query_vars['post_type'] );
-			} else {
-				$this->query_vars['post_type'] = array_intersect( $this->query_vars['post_type'], $queryable_post_types );
+		if ( isset( $this->query_vars['post_type'] ) ) {
+			// Limit publicly queried post_types to those that are publicly_queryable
+			$queried_post_types = array_intersect(
+				(array) $this->query_vars['post_type'],
+				get_post_types( array( 'publicly_queryable' => true ) )
+			);
+
+			// Limit post type archives to those with has_archive
+			if ( !is_admin() && !empty( $queried_post_types ) && !isset( $this->query_vars['name'] ) ) {
+				$valid_ptypes = array();
+				foreach( $queried_post_types as $ptype ) {
+					if ( get_post_type_object( $ptype )->has_archive )
+						$valid_ptypes[] = $ptype;
+				}
+				$queried_post_types = $valid_ptypes;
 			}
+
+			if ( empty( $queried_post_types ) )
+				unset( $this->query_vars['post_type'] );
+			elseif ( is_array( $this->query_vars['post_type'] ) )
+				$this->query_vars['post_type'] = $queried_post_types;
+			else
+				$this->query_vars['post_type'] = $queried_post_types[0];
 		}
 
 		foreach ( (array) $this->private_query_vars as $var) {
