Pumpkin-MC/Pumpkin · error · LicenseError
Plugin is unsigned or missing marketplace metadata
Error message
Plugin is unsigned or missing marketplace metadata
What it means
LicenseError::UnsignedPlugin is a fieldless variant indicating the plugin carries no signature or is missing marketplace metadata entirely, so license verification cannot even identify it. Unlike MetadataMismatch (metadata present but wrong), this fires when the required marketplace/signature data is absent.
Solutions
- Install the plugin from the official marketplace so signed metadata is present.
- Rebuild with the official publishing toolchain that embeds signing/marketplace metadata.
- Do not repackage/rezip the plugin jar, which can drop metadata.
- Verify the correct plugin file is license-gated; unsigned free plugins should skip license checks.
- If you believe the plugin is signed, verify the jar's manifest contains the marketplace metadata keys.
Example fix
// before (manual repackage) zip -r myplugin.jar extracted/ // metadata lost -> UnsignedPlugin // after mvn pumpkin:publish && install dist/myplugin-1.2.0.jar // signed build
Defensive patterns
Strategy: validation
Validate before calling
// Verify the packaged plugin carries marketplace metadata before enabling license flow
let jar = std::fs::File::open("plugins/myplugin.jar")?;
let mut archive = zip::ZipArchive::new(jar)?;
let manifest = archive.by_name("META-INF/MANIFEST.MF")?;
let text = std::io::read_to_string(manifest)?;
if !text.contains("Marketplace-Id") {
panic!("plugin jar lacks marketplace metadata — rebuild via official pipeline");
} Type guard
fn is_unsigned(e: &LicenseError) -> bool {
matches!(e, LicenseError::UnsignedPlugin)
} Try / catch
match manager.verify() {
Err(LicenseError::UnsignedPlugin) => {
tracing::error!("plugin is unsigned; install official marketplace build");
disable_paid_features();
}
other => other.map(|_| ()),
} Prevention
- Install plugins only from the official marketplace.
- Never rezip/repackage plugin jars.
- Build with the official publishing toolchain that signs artifacts.
- Skip license checks for genuinely free unsigned plugins.
When it happens
Trigger: Running license checks on a plugin built locally or distributed outside the marketplace without embedded signing/marketplace metadata; metadata stripped by repackaging; loading a jar whose manifest lacks the expected marketplace entries.
Common situations: Developer testing an in-development build through the paid-plugin flow; third-party mirror site download with metadata stripped; unzip/rezip of the plugin losing manifest entries; mixing up a free unsigned plugin with a license-gated one.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- License metadata mismatch
- Missing plugin metadata
- Marketplace HTTP error
- License was revoked or refunded
- License has expired on
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/cb2ee584d3fd629b.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-plugin-utils/src/license.rs:36
#[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.
pub struct LicenseChecker {
data_folder: PathBuf,
http_client: HttpClient,
}
impl LicenseChecker {
/// Creates a new `LicenseChecker` instance for the given data folder.
#[must_use]
pub fn new(data_folder: impl AsRef<Path>) -> Self {View on GitHub (pinned to 8d4639e25a)