License Issues
This page covers common problems related to license activation, validation, activation counting, and grace period behaviour. Each issue is presented with its symptoms, likely causes, diagnostic steps, and solution.
License Not Activating
Symptom
A customer enters their license key into your plugin or theme and receives an error such as License key is invalid, Activation limit reached, or License is not active. The activation request fails and the product remains unlicensed on their site.
Likely Causes
- Wrong key format. LicenceForge keys follow the
XXXX-XXXX-XXXX-XXXXformat (four groups of four alphanumeric characters separated by hyphens). If the customer has copied extra whitespace, missing hyphens, or partial key segments, the lookup will fail. - Activation limit reached. The license has already been activated on the maximum number of sites allowed by its price tier. Further activations are blocked until an existing site is deactivated.
- License expired, suspended, or cancelled. Only licenses with an
activeortrialstatus can be activated. Expired licenses (past the grace period), suspended licenses, and cancelled licenses all reject activation attempts. - Fingerprint mismatch. If device fingerprinting is enabled for the product, the server fingerprint sent with the activation request must match the fingerprint on record. A mismatch (for example, after a server migration) causes the activation to be rejected.
Diagnostic Steps
- Navigate to LicenceForge > Licenses and search for the license key (or the last four characters).
- Confirm the Status column shows
ActiveorTrial. - Check the Sites column. If the fraction shows the limit is reached (e.g.,
5 / 5), activations are blocked. - Open the license detail view and inspect the Expires field. If the date has passed, check whether the grace period has also elapsed.
- If fingerprinting is enabled, compare the fingerprint stored on the activation record with the one being sent by the client. You can find activation records under the Activations tab on the license detail page.
- Check the
wplf_audit_logtable for the most recent activation attempt. Theoutcomeandmetadatacolumns will contain the specific rejection reason.
Solution
Key format
Ask the customer to copy the key directly from their license email or account page. Ensure the key follows the XXXX-XXXX-XXXX-XXXX pattern with no leading or trailing whitespace.
- Activation limit: Deactivate an unused site from the license detail page (click the site URL, then Deactivate), or increase the activation limit on the associated price tier.
- Expired license: If the license should still be valid, update the expiration date or change the status back to
activefrom the license edit page. - Suspended or cancelled: Review the audit log to determine why the license was suspended or cancelled, then change the status if appropriate.
- Fingerprint mismatch: If the customer has migrated servers, clear the stored fingerprint on their activation record. The next activation request will store the new fingerprint automatically.
License Showing as Invalid
Symptom
A license that was previously working now fails validation. The client plugin reports License key is invalid even though the customer has not changed the key. The license may appear as Expired in the admin panel.
Likely Causes
- Expired beyond the grace period. When a license expires, it enters a grace period (configurable via
wplf_grace_period_days, default 3 days). During the grace period, the license still validates successfully. Once the grace period elapses, the daily maintenance cron (wplf_daily_maintenance) changes the status toexpiredand validation fails. - Key was rotated. If an administrator performed a key rotation, the old key is invalidated immediately. The customer must use the new key provided after rotation.
- Product slug mismatch. The product slug sent in the validation request does not match the slug configured on the product in LicenceForge. This can happen if the product slug was changed after the client plugin was distributed, or if the client plugin has a hardcoded slug that differs from the one in the database.
Diagnostic Steps
- Search for the license key in LicenceForge > Licenses. If the key is not found, it may have been rotated -- check the audit log for
key_rotatedevents for that customer. - If the license is found, check its Status and Expires fields. Calculate whether the grace period has passed.
- Verify the product slug by navigating to LicenceForge > Products and comparing the slug in the Slug column with the value your client plugin sends in the
product_slugparameter. - Inspect the audit log for the failed validation attempt. The
metadatacolumn will specify whether the failure was due to an unknown key, expired status, or slug mismatch.
Solution
- Expired license: Renew the license by updating the expiration date and setting the status back to
active. If the customer has an active subscription, check that theinvoice.payment_succeededwebhook is properly extending the expiration (see Payment Issues). - Rotated key: Provide the customer with their new license key. The new key is available on the license detail page and was sent via the key rotation notification email.
- Slug mismatch: Either update the product slug in LicenceForge to match the client plugin, or update the client plugin to send the correct slug. Changing the slug in LicenceForge is usually simpler, but ensure no other integrations depend on the current slug.
Warning
Changing a product slug affects all API endpoints and client validation requests for that product. Coordinate slug changes with any distributed client libraries to avoid breaking existing installations.
Activation Count Wrong
Symptom
The license detail page shows an activation count that does not match reality. For example, a customer has deactivated a site but the count still reflects it as active, or the Sites column shows 3 / 3 when the customer believes only one site is active.
Likely Causes
- Deactivated sites not releasing count. When a site is deactivated through the LicenceForge API, the
deactivated_attimestamp is set on the activation record in thewplf_activationstable. The active count is calculated by counting rows wheredeactivated_at IS NULL. If the deactivation request did not complete successfully (for example, due to a network timeout), the row retains a nulldeactivated_atvalue and the site is still counted as active. - Stale activation records. Sites that were uninstalled or abandoned without properly deactivating the license leave behind orphan activation records. These records have no
deactivated_attimestamp and continue to consume activation slots.
Diagnostic Steps
- Open the license detail page and click the Activations tab to view all activation records.
- Identify any records where the Status shows
Activebut the site URL is no longer in use or the customer confirms that site is deactivated. - For a direct database check, query the
wplf_activationstable:
SELECT id, site_url, activated_at, deactivated_at, last_seen_at
FROM wp_wplf_activations
WHERE license_id = <LICENSE_ID>
AND deactivated_at IS NULL;
This query returns all activation records that are currently counted as active. Any rows where the site_url corresponds to a site that should no longer be active indicate the problem.
Solution
- Manual deactivation: From the Activations tab on the license detail page, click Deactivate next to any site that should no longer be active. This sets the
deactivated_attimestamp and frees the activation slot. - Auto-deactivation for stale sites: If the
wplf_auto_deactivateoption is enabled, the daily maintenance cron will automatically deactivate sites that have not sent a validation request (checked vialast_seen_at) within the configured inactivity period. Ensure this option is enabled in LicenceForge > Settings. - WP-CLI bulk fix: To deactivate all stale activations for a specific license from the command line:
wp eval "
global \$wpdb;
\$table = \$wpdb->prefix . 'wplf_activations';
\$wpdb->query(
\$wpdb->prepare(
\"UPDATE \$table SET deactivated_at = NOW() WHERE license_id = %d AND deactivated_at IS NULL AND last_seen_at < DATE_SUB(NOW(), INTERVAL 30 DAY)\",
<LICENSE_ID>
)
);
"
Note
Replace <LICENSE_ID> with the numeric ID of the license from the wplf_licenses table, and adjust the 30-day interval to match your preferred inactivity threshold.
Grace Period Not Working
Symptom
A license expires and immediately begins failing validation, with no grace period. The customer expects a few days of continued access after expiration, but the license is marked as expired right away.
Likely Causes
- Grace period set to zero. The
wplf_grace_period_daysoption controls how many days after expiration a license remains valid. If this value is set to0, there is no grace period and the license transitions toexpiredon the next daily maintenance run after the expiration date. - Option missing or misconfigured. If the
wplf_grace_period_daysoption was accidentally deleted from thewp_optionstable, the plugin may fall back to a default that differs from what you expect. - Cron timing. The
wplf_daily_maintenancecron event runs the expiration check. If the cron fires shortly after midnight and the license expired that same day, the grace period calculation may appear to skip a day depending on time zones.
Diagnostic Steps
- Check the current grace period value in LicenceForge > Settings. The field is labelled Grace Period (days).
- Alternatively, check the value directly from the database or WP-CLI:
wp option get wplf_grace_period_days
The default value is 3. A value of 0 means the grace period is disabled.
- Verify that the daily maintenance cron is running by checking the cron schedule:
wp cron event list | grep wplf_daily_maintenance
- Review the audit log for the license in question. Look for a
license_expiredevent and compare its timestamp with the license expiration date to determine whether the grace period was applied.
Solution
- Set the grace period: Navigate to LicenceForge > Settings and set the Grace Period (days) field to your desired value (e.g.,
3for a 3-day grace window). Save the settings. - Restore a missing option: If the option is missing from the database, recreate it:
wp option update wplf_grace_period_days 3
- Time zone alignment: Ensure your WordPress time zone setting (Settings > General > Timezone) matches your intended behaviour. LicenceForge uses the WordPress-configured time zone for all date calculations, including grace period expiration.
- Cron not running: If the daily maintenance cron is not scheduled, re-schedule it by deactivating and reactivating LicenceForge, or manually trigger it:
wp cron event run wplf_daily_maintenance
Related Pages
- License Lifecycle -- States, transitions, and grace period behaviour
- Activations -- Activation tracking and deactivation management
- Device Fingerprinting -- Fingerprint configuration and mismatch handling
- Debug Mode -- Enable logging to diagnose license issues in detail