"Sync is stuck" is the single most reported support issue across every Clover-to-WooCommerce plugin. It's rarely one bug — it's usually one of seven distinct failure modes, each with its own fix. This playbook walks through all seven in the order we check them on real support tickets.
1. Queue wedged on a single bad record
Background sync queues process one job at a time. If a particular product or order has malformed data (null SKU, invalid price, circular category reference), the worker hits an exception, retries with exponential backoff, and eventually blocks every job behind it.
Fix: open the plugin's queue log. Find the oldest failed job. Look at the payload — fix the source record in Clover (or Woo) so it validates, then requeue. If the record is genuinely unfixable, skip it to unblock the queue.
2. Clover API rate limit
Clover enforces rate limits per merchant. On initial bulk syncs or unusually heavy days, plugins can exceed those limits and get 429 responses. If the plugin's rate-limit handler doesn't back off correctly, the queue stalls.
Fix: check plugin logs for HTTP 429 responses. Confirm the rate-limit backoff is working (CloverWoo has this built in with a tuned delay). If you're hitting limits on a bulk import, run the import in smaller batches (500 records at a time).
3. OAuth token expired or revoked
Every Clover API call carries an OAuth access token. If that token expires or gets revoked (user action, token rotation), every subsequent call returns 401, and the queue starts erroring.
Fix: from plugin settings, click 'Reconnect to Clover'. Complete OAuth. Confirm green 'Connected' status. The queue resumes automatically.
4. Conflict resolution loop
If both Clover and WooCommerce update the same record, the plugin's conflict rule decides who wins. But if webhook events fire in a specific order, you can get a loop: Clover event updates Woo, which fires a Woo webhook, which updates Clover, which fires a Clover webhook, and so on.
Fix: CloverWoo's checksum-based change detection prevents most loops — it recognizes that a just-updated record matches the source and stops propagating. If you're seeing a loop in another plugin, tighten the conflict rule (e.g. 'Clover wins' as a strict one-way) for the affected record type.
5. Single corrupted product blocking others
Related to cause 1 but more specific: a product with a broken image URL, an image too large, or a variable product with missing parent gets stuck mid-sync. Subsequent products queue up behind it.
Fix: identify the stuck SKU in logs. Fix or delete it in both Clover and Woo. Restart the queue.
6. Webhook gap + cron disabled
Some merchants turn off WordPress cron to reduce server load. If webhooks also stop (see our webhooks guide), nothing triggers sync jobs and the queue goes quiet. It's not stuck — it's just not running.
Fix: confirm either WordPress cron is running (WP-Cron.php hitting) or a system cron calls it every minute. Confirm webhooks are firing via Clover's delivery log.
7. PHP memory exhaustion
Large bulk syncs on sites with low PHP memory limits (under 256MB) crash mid-batch, leaving the queue in an indeterminate state. WordPress logs show 'Allowed memory size exhausted' errors.
Fix: bump PHP memory to at least 512MB for the site (set WP_MEMORY_LIMIT in wp-config.php). For heavy bulk imports, 1GB is safer.
Recovery procedure
- Stop the queue worker from the plugin dashboard.
- Review the oldest 20 failed jobs — almost always 1–3 records are the root cause.
- Fix or skip those records.
- Clear stale locks if the plugin supports it.
- Restart the queue worker.
- Run a manual sync of the affected record types to catch anything missed during the outage.
- Monitor for 30 minutes and confirm job throughput matches your normal volume.
Frequently asked questions
How do I tell if sync is actually stuck vs just slow?
Compare queue depth now vs an hour ago. If depth is growing while jobs-per-minute is near zero, sync is stuck. If depth is steady or shrinking, it's just processing a large batch.
Will restarting the queue lose data?
No, if your plugin uses a persistent queue (CloverWoo does). Jobs are stored on disk or in the database and survive restarts.
Can I safely skip a failed record?
Usually yes — if it's a single record that won't validate, skipping unblocks everything else. Just don't forget to fix the source record so it doesn't re-enter the queue and fail again.
How do I prevent this from recurring?
Monitor queue depth, run a daily reconciliation report that flags records where Clover and Woo disagree, and keep PHP memory above 512MB.