Maintenance policy implementation

EDIT May16th: Using LexActivator 3.21.2

Are there any more detailed documentation and examples how this is supposed to be implemented.

I have a maintenance policy having limited time, immediate expiration, AllowMajorVersionUpdates=true, AllowMajorVersionUpdates=true.

I am trying to figure out how this works. Doc tells to call (after SetProductId()) these functions:
SetReleaseVersion();
SetReleasePublishedDate();

In call to SetReleasePublishedDate() I pass the release publish time as Unix epoch time. After these I had a call to GetLicenseMaintenanceExpiryDate() for logging and verification. Maintenance expiration date looks fine.

I have changed the target date/time past the maintenance expiration and still able to update to any SW version; either major or minor increasing. My latest ReleasePublishedDate also exceeds maintenance expiration date…still updates are fine.

Then I just tried to call GetLicenseMaintenanceExpiryDate() between those two
SetReleaseVersion();
GetLicenseMaintenanceExpiryDate()
SetReleasePublishedDate();

Now GetLicenseMaintenanceExpiryDate() returns LA_E_RELEASE_VERSION_NOT_ALLOWED. Expiration date “returned” in this case is 0, which is a bit annoying.
If I ignore the return value of GetLicenseMaintenanceExpiryDate(), validation still says all good.

So, I’m pretty confused how this should be implemented.
How am I supposed to use SetReleasePublishedDate()?
I though that GetLicenseMaintenanceExpiryDate() is just to read&know the expiration time. But it also does some version checking?
GetLicenseMaintenanceExpiryDate() is not even mentioned here in related documents:

Most probably I have totally misunderstood something…therefore advise needed.

Hi @navimo,

Thank you for reaching out.

It appears that you are currently using an older version of LexActivator. Since then, we have implemented several bug fixes, including updates related to Maintenance Policies as well. We recommend upgrading to the latest version, v3.31.3, and then retrying the steps you outlined. Once you have done that, we would greatly appreciate it if you could share the results with us.

Regarding the SetReleasePublishedDate() function, this is only necessary if you are not using our Release Management System. If you are using it, the release date is automatically derived from the system, and there is no need to call this function manually.

I updated the LexActivator to 3.31.3. The following is the call order in my code (OPT_A and OPT_B explained later).

SetProductData
SetProductId
SetLicenseKey
OPT_A: GetLicenseMaintenanceExpiryDate
SetReleaseVersion
OPT_B: GetLicenseMaintenanceExpiryDate
SetReleasePublishedDate
IsLicenseValid

First test case I used is such that maintenance policy is defined AND expired.
SW version updated and published date is beyond maintenance expiration date.
Some different cases below - only changing thing is when GetLicenseMaintenanceExpiryDate is called

  1. GetLicenseMaintenanceExpiryDate() called in position OPT_A
    GetLicenseMaintenanceExpiryDate() returns LA_OK, and ExpiryDate read seems fine
    IsLicenseValid() also returns LA_OK - this was unpleasant surprise

  2. GetLicenseMaintenanceExpiryDate() called in position OPT_B
    GetLicenseMaintenanceExpiryDate() returns LA_E_RELEASE_VERSION_NOT_ALLOWED, and ExpiryDate is 0
    IsLicenseValid() also returns LA_E_RELEASE_VERSION_NOT_ALLOWED

  3. GetLicenseMaintenanceExpiryDate() not called at all
    IsLicenseValid() returns LA_E_RELEASE_VERSION_NOT_ALLOWED

So, when and where GetLicenseMaintenanceExpiryDate() is called, has major effect on behavior, and effects on return value of IsLicenseValid(). Clearly GetLicenseMaintenanceExpiryDate() is doing something else than just:
PURPOSE: Gets the license maintenance expiry date timestamp.

What I would like to do (and assumed that too) is that I can call GetLicenseMaintenanceExpiryDate() and always get the expiry date if such is defined. And doing that without any side-effects. And IsLicenseValid() then validating the license. This is not how this now works.

So, I would really like to have a short explanation how these functions work together, and some guideline for best practices.

Still, about this SetReleasePublishedDate(). Let’s say that Maintenance policy allows for example MInor updates and has a limited time. When that limited time has expired, then last version validated is known…so, don’t really see what this publish date is needed for.

Hi @navimo,

I would like to clarify why the behavior of GetLicenseMaintenanceExpiryDate() changes depending on where it’s called in your flow.

In the first test case:
GetLicenseMaintenanceExpiryDate() internally invokes IsLicenseValid() function. Since, you are calling SetReleaseVersion() function after GetLicenseMaintenanceExpiryDate() function due to which the release validation checks are bypassing.

In the second test case:
Here, the release version is set before calling any getter functions. That means the SDK is now aware of the release version when GetLicenseMaintenanceExpiryDate() is called and it correctly returns LA_E_RELEASE_VERSION_NOT_ALLOWED, because the release date is beyond the maintenance expiry date. This is an expected behavior, as the validation checks now include the release version constraints.

Correct Flow (Recommended):
To ensure all validation checks including release validation work as intended, the function calls should follow this sequence:

SetProductData()
SetProductId()
SetLicenseKey()
SetReleaseVersion()
SetReleasePublishedDate()
IsLicenseValid()
GetLicenseMaintenanceExpiryDate() //Now returns accurate results based on proper validation

Note: If you are using our release management system, the release’s published date is automatically retrieved and validated internally. In that case, calling SetReleasePublishedDate() is not necessary. However, if you are not using it, you will need to explicitly set the published date using SetReleasePublishedDate() to ensure the validation behaves as expected. The SetReleasePublishedDate() function is required in scenarios where the maintenance policy has expired and the release’s published date is after the maintenance expiry date, indicating that the user should not be allowed to access that release. Conversely, if the release was published before the maintenance expiry date, the user should be allowed to use it, even if the current date is beyond the maintenance expiry.

Ok, thx. I’ll proceed with this info.

1 Like

I have been busy, but did some testing today using node locked license.
Increasing SW version numbers and setting system date to future. Stopped here.

System date: Sat 20 Nov 2027 06:00:59 PM CET

SetProductData - Success
SetProductId - Success
SetLicenseKey - Success
SetReleaseVersion - Success
releasePublishedDate: 2027.11.11 (1825934400)
SetReleasePublishedDate - Success
IsLicenseValid - Success
GetLicenseMaintenanceExpiryDate - Success
Maintenance Expiry Date: 2026.09.06 (1788684390)

Now everything just returns OK all the time…even if system date and releasePublishedDate are way beyond Maintenance Expiry Date. I did quick test moving GetLicenseMaintenanceExpiryDate call to earlier point (as in my old post). No matter where i called it, license was ok all the time.

While testing I used same license and disabled/enabled Maintenance Policy few times. Could that mess things??

EDIT: Plus when I changed my system time back to normal: Tue 27 May 2025 04:06:30 PM CEST
I was able to start my SW without any complaints related to time tampering!??!

EDIT2: Plus with quick testing GetLicenseMaintenanceExpiryDate fails for Floating license? Should it work?

The GetLicenseMaintenanceExpiryDate() function is expected to successfully return the expiry date for Hosted-Floating licenses as well.

However, we have not been able to reproduce the issues you reported above. We recommend trying to reproduce the behavior using one of our sample projects available at Github, and sharing your observations with us. Also, please confirm the current release version configured for the license and the allowed clock offset value. You can share all these details with us at support@cryptlex.com.