Pumpkin-MC/Pumpkin · error · LicenseError

License has expired on

Error message

License has expired on {0}

What it means

LicenseError::Expired means the plugin's license has passed its expiry date; the date is included via {0}. The marketplace or local lease validation determined the license term ended, so continued use is not permitted.

Solutions

  1. Renew the license/subscription on the marketplace.
  2. Verify server system clock/NTP is correct (wrong clock is a common false expiry).
  3. Re-run verification after renewal to refresh the cached lease.
  4. If the marketplace shows an active license, re-sync/re-verify to update local cache.
  5. Contact marketplace support if expiry date ({0}) contradicts your account.

Example fix

// before
let license = manager.verify()?; // Expired
// after
match manager.verify() {
    Err(LicenseError::Expired(date)) => {
        tracing::error!("license expired on {date}; renew at marketplace");
        prompt_renewal(date);
    }
    r => r?,
}
Defensive patterns

Strategy: validation

Validate before calling

// Check expiry locally from the cached lease before the license check fails
if let Ok(lease) = load_cached_lease() {
    if lease.expires_at <= chrono::Utc::now() {
        tracing::warn!("license already expired at {} — renew first", lease.expires_at);
    }
}

Type guard

fn is_expired(e: &LicenseError) -> bool {
    matches!(e, LicenseError::Expired(_))
}

Try / catch

match manager.verify() {
    Err(LicenseError::Expired(date)) => {
        tracing::error!("license expired {date}; renewing required");
        notify_admin_renewal(date);
    }
    other => other.map(|_| ()),
}

Prevention

When it happens

Trigger: License verification finds the license's expiry timestamp in the past — either reported by the marketplace API or computed from the cached lease after the offline grace period plus expiry have both lapsed.

Common situations: Annual/subscription license ran out; trial license ended; server clock set far in the future (system time skew) making a valid license look expired; renewal payment failed silently.

Related errors


AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09). Data as JSON: /api/errors/83daf615a15ad759. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin-plugin-utils/src/license.rs:27

    time::{Duration, SystemTime, UNIX_EPOCH},
};
use thiserror::Error;
use tracing::{debug, info};

/// License checking and verification errors.
#[derive(Debug, Error)]
pub enum LicenseError {
    /// HTTP communication error with marketplace.
    #[error("Marketplace HTTP error: {0}")]
    Http(#[from] HttpError),
    /// Metadata validation error (e.g. missing license on paid plugin).
    #[error("License metadata mismatch: {0}")]
    MetadataMismatch(String),
    /// License revoked or refunded by marketplace.
    #[error("License was revoked or refunded: {0}")]
    Revoked(String),
    /// License is expired.
    #[error("License has expired on {0}")]
    Expired(String),
    /// I/O error reading/writing license cache.
    #[error("I/O error with license storage: {0}")]
    Io(#[from] std::io::Error),
    /// JSON serialization error.
    #[error("JSON serialization error: {0}")]
    Json(#[from] serde_json::Error),
    /// Plugin is unsigned or missing marketplace metadata.
    #[error("Plugin is unsigned or missing marketplace metadata")]
    UnsignedPlugin,
    /// Plugin has not been initialized.
    #[error(
        "Plugin-utils has not been initialized (call pumpkin_plugin_utils::init(context) first)"
    )]
    NotInitialized,
}

/// Manages license checks, cached leases, and offline grace periods.

View on GitHub (pinned to 8d4639e25a)