Registering a custom post type does not create its rewrite rules, so the archive 404s until permalinks are re-saved. The fix that circulates is flush_rewrite_rules() on init, which works and rebuilds the entire rule set on every single request.
// wrong: rebuilds and writes an option on every request
add_action( 'init', 'flush_rewrite_rules' );
// right: once, when the rules have actually changed
add_action( 'init', function () {
if ( get_option( 'myplugin_rewrites' ) !== '1.4.0' ) {
flush_rewrite_rules( false );
update_option( 'myplugin_rewrites', '1.4.0' );
}
}, 99 );
The rebuild walks every registered rule and writes the result to the options table — measurable on a site with a few plugins, and pointless when nothing has changed. Version-gating it means the flush happens once per deploy. Registering the post type on plugin activation instead does not help on its own, because activation runs before init.