Troubleshooting
Common issues with FCHub Memberships and how to resolve them.
This page covers the most common issues you might encounter with FCHub Memberships and how to diagnose and fix them.
Content Not Protected
Symptoms: Non-members can see content that should be restricted.
Diagnosis steps:
Check if the resource is protected
Go to Memberships > Content and verify the resource has a protection rule. Alternatively, edit the post and check the Membership Protection meta box.
If the post is protected through plan rules (not explicit protection), verify the plan has the correct content rules in its Content Rules tab.
Check the plan status
Go to Memberships > Plans and make sure the plan status is active. Draft or inactive plans don't enforce protection.
Check admin bypass
By default, administrators bypass all protection. Log in as a non-admin user to test, or temporarily disable admin bypass in Memberships > Settings (admin_bypass = "No").
Check caching
If you use a page caching plugin (WP Super Cache, W3 Total Cache, LiteSpeed Cache, etc.), cached pages will serve the same content to all visitors. You need to:
- Exclude protected pages from the cache, or
- Use a cache plugin that supports user-level caching (varies content by logged-in state)
Verify the hook priority
ContentProtection hooks into the_content at priority 999. If another plugin removes or overrides content at a later priority, protection may be bypassed. Check for plugins that modify the_content at priority 1000+.
Make sure the taxonomy protection rule has inheritance_mode set to all_posts. Without this, the taxonomy term is protected but individual posts in that term are not.
Also verify the post is actually assigned to the protected taxonomy term.
The plugin filters REST API responses via rest_prepare_{post_type} hooks. Make sure the post type has show_in_rest => true and public => true — the hooks are only registered for public REST-enabled post types.
Access Not Granted After Purchase
Diagnosis steps:
Check the integration feed
Go to the FluentCart product editor and verify the Memberships integration feed is present and enabled. Check that:
- A plan is selected
- The event trigger includes
order_paid_done - The feed is not disabled
Check event locks
The plugin uses an event lock table to prevent duplicate processing. If a feed fired but encountered an error, it may have created a lock that prevents re-processing. Check the fchub_membership_event_locks table for entries with result = 'error'.
Check the order status
The integration feed only fires on paid orders. Make sure the FluentCart order status is "Paid" or "Completed". Pending or failed orders do not trigger membership grants.
Check the order log
In the FluentCart order detail page, look at the order notes/log. The membership integration logs messages like "Membership access granted" or "Membership grant skipped" with details about what happened.
Check for user mismatch
The integration resolves the user from the order. If the order has no user_id and no matching email account exists, the user might not be found. Check if "Auto-Create User" is enabled in the feed settings.
- Check the grant status in Memberships > Members — it should be
active - Check if the grant has a
starts_atdate in the future - Check if the grant has an
expires_atdate in the past - Check if the content is drip-locked (check
drip_available_at) - Check if the membership is paused (status =
paused) - Use WP-CLI to debug:
wp fchub-membership debug --member=<email>
Drip Content Issues
Drip unlock notifications are processed by the fchub_memberships_drip_process hourly cron. If content is not unlocking:
- Check WP-Cron — Go to Tools > Site Health and verify WP-Cron is running. If your site has low traffic, WP-Cron may not fire regularly. Consider setting up a real cron job:
*/5 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1-
Check the drip_available_at field — The
drip_available_atcolumn on the grant record should have the expected unlock date. If it's null, the drip rule might not have been applied correctly during grant creation. -
Check the notification queue — Go to the drip admin page and look at the notification queue. Failed notifications can be retried individually.
-
Force processing — Run
wp fchub-membership drip-processfrom the command line to process pending notifications immediately.
- Check that
email_drip_unlockedis set to "Yes" in settings - Check Action Scheduler for pending or failed
fchub_memberships_send_emailactions - Check the notification's
retry_count— after 3 failures, notifications are permanently marked as failed - Verify basic WordPress email delivery works (use WP Mail SMTP or a test email plugin)
Email Issues
- Check the email setting — Each email type can be individually disabled. Verify the specific email is enabled in Memberships > Settings
- Check Action Scheduler — Go to Tools > Scheduled Actions and look for
fchub_memberships_send_emailentries. Pending actions are queued but not yet processed. Failed actions show error details - Check wp_mail — Test basic email delivery with another plugin. FCHub Memberships uses standard
wp_mail()for delivery - Check From address — Emails are sent from your
admin_email. Make sure your email provider doesn't reject these (SPF/DKIM configuration)
The emails are sent as HTML (Content-Type: text/html; charset=UTF-8). If they arrive as plain text:
- Check if another plugin is forcing plain text emails
- Check if your mail provider strips HTML
- Verify the email headers include the Content-Type header
FluentCRM Issues
FluentCRM automation components boot at init priority 30. If triggers are not firing:
- Verify FluentCRM is active — The
FLUENTCRMconstant must be defined - Check boot timing — The automation module loads at init priority 30. If the membership event fires before priority 30 (during early init), the trigger might not be registered yet. Normal purchase flows fire well after init, so this should only affect custom code that fires events very early
- Check the automation — Make sure the FluentCRM automation is published and active
- Check the contact — The trigger needs a FluentCRM contact with a matching WordPress user. If the contact doesn't exist, the trigger won't fire
Smart codes resolve data from the contact's latest active grant. If they return empty:
- The contact may not have a
user_idset in FluentCRM - The user may not have any active grants
- For coupon-related smart codes, verify a CreateFluentCartCoupon action has run for this contact
Subscription Sync Issues
The SubscriptionValidityWatcher checks subscription validity every 5 minutes via the fchub_memberships_validity_check cron.
- Check the grant's source_type — It should be
subscription, notorder. The V3 migration fixes grants that were incorrectly created withsource_type = 'order'. If you see grants withsource_type = 'order'that should besubscription, re-run migrations by incrementing the DB version in settings - Check WP-Cron — The validity check runs every 5 minutes. Verify cron is executing
- Check the feed settings — If "Cancellation Behavior" is set to "Keep access until validity expires", the grant won't be revoked immediately on cancellation — it waits for the
expires_atdate
The V3 migration automatically fixes grants that should have source_type = 'subscription' but were created with source_type = 'order'. It detects this by joining the grants table with FluentCart's subscriptions table.
If you suspect grants still have the wrong source_type:
wp fchub-membership debug --member=<email>This shows the grant details including source_type and source_ids.
Performance Issues
The AccessEvaluator uses two levels of caching:
- Per-request cache — static array, zero overhead on repeated checks within the same request
- Transient cache — WordPress transients with 5-minute TTL for batch access checks (used in archive filtering)
If pages with many protected items are slow:
- Check if archive filtering is scanning too many posts. The
canAccessMultiple()method uses batch checking with transient caching - Consider using an object cache plugin (Redis, Memcached) to speed up transient reads
- Check if a caching plugin can cache member-specific pages
The plugin creates indexes on all frequently-queried columns. If queries are still slow:
- Check that indexes were created successfully during migration
- For very large grant tables (100k+ rows), consider the
purge-expiredWP-CLI command to remove old expired/revoked grants - The audit log is cleaned up weekly (entries older than 90 days). If it's grown large, you can run manual cleanup