WooCommerce products showing “Out of stock” message when not actually out of stock

I had this same problem and I think I figured it out. I used the CSV Import/Export suite to export all of my variations. You'll notice that stock is set to 0 when it should have a value of null.

You have two options here:

  1. Go into each individual product, click the variations tab and expand each variation - unchecking the "manage stock" checkbox:enter image description here
  2. You can do a find-and-replace on the database substituting the 0 value for null.

I was getting this same issue with a product I had newly created. But for me the answer was more simple.

I needed to enter in a “Regular Price” for every variation.
https://wordpress.org/support/topic/this-product-is-currently-out-of-stock-and-unavailable-4/

I had created my attributes previously.

Under Variations, for my product, I had to make sure “Add variation” was selected. Then I clicked the “Go” button.

I needed to create a variation for each of the different choices the attribute could have.

So for my Color Options I had to make three different variations (one for each choice).
Then I needed to click the blue “Expand” text, and make sure each variation had a Regular price.

Then it worked. enter image description here

(This was helpful too: https://docs.woocommerce.com/document/variable-product/ )


It's 2017 and I'm still seeing the OP's exact problem on a store running:

  • WordPress 4.8.1
  • WooCommerce 3.1.2
  • PHP 5.6
  • tons of plugins and a janky theme

I don't have the time to genuinely fix the bug--whatever it is--but I made a workaround.

The problem is that $product is missing everything variation related. There are no variation IDs, attributes, or prices. My workaround fixes up $product before it gets used in the templates.

Step 1: Copy the price.php template into your theme. Navigate to your WooCommerce's price template at /wp-content/plugins/woocommerce/templates/single-product/price.php. Copy that into your theme at /wp-content/themes/my-theme/woocommerce/single-product/price.php. If you already have that file there, then you already have a custom price.php template and you can skip this step.

Documentation on how WooCommerce custom templates work: https://docs.woocommerce.com/document/template-structure/

Step 2: Edit that price.php you just put in your theme. Below global $product; paste this:

if ( $product->is_type( 'variable' ) ) {
  // this is a variable product, so let's ensure $product is set up correctly

  // force the product to sync with its variations
  $product->sync( $product->id );
  // update $product with the synced product
  $pf = new WC_Product_Factory();
  $product = $pf->get_product( $product->id );
  // update utility variables used in the variable.php template
  $available_variations = $product->get_available_variations();
  $attributes = $product->get_variation_attributes();
}

I had some caching issues that made it appear as though it wasn't working at first. To test if it's working you can drop

echo '<pre style="display: none;">';
print_r( $product );
echo '</pre>';

at the top and bottom of the if. Now you can inspect the page, and just above the price will be the two hidden <pre> containing $product before and after fixing.

This works by using the sync() function to force the product to grab all the missing variation info, and then updates variables for use in templates. I believe the price is the earliest any of the variation data gets used in the templates, but this snippet could easily go higher up in the template chain if needed.

Edit: The above fix only works for WooCommerce 3.x. I did create a fix for WC 2.x but it is so huge and gross I'm not going to post it. If you still have a 2.x store you need to look into some sort of overhaul that will allow you to get on 3.x.


Edit: My problem recurred - items became outofstock again after a time. In searching around, I found that there are more entries in the wp_postmeta table to be concerned with thanks to this post. Below, I've added 2 additional update functions that should help make the fix last forever.

One cause of this problem is that the stock status may be recorded as "outofstock" in the database, even while manage inventory is disabled.

You can check if this is your problem in phpMyAdmin by running:

SELECT * FROM `wp_postmeta` WHERE `meta_key` = '_stock_status'

If you see that items are "outofstock" but are expected to be "instock," you can change them manually. Or, you can run:

UPDATE `wp_postmeta` SET `meta_value` = 'instock' WHERE `meta_key` = '_stock_status';
UPDATE `wp_postmeta` SET `meta_value` = '999999999' WHERE `meta_key` = '_stock';
UPDATE `wp_postmeta` SET `meta_value` = 'no' WHERE `meta_key` = '_manage_stock';