Pumpkin-MC/Pumpkin · error · LicenseError
Marketplace HTTP error
Error message
Marketplace HTTP error: {0} What it means
LicenseError::Http wraps any HttpError (#[from]) raised while communicating with the marketplace's license/verification REST API. It means the license check could not complete due to an HTTP-level failure (request failed, non-2xx status, or unreadable body), not a licensing decision.
Solutions
- Read the inner HttpError ({0}) to distinguish request-failure vs bad status vs body-read.
- Verify marketplace base URL and credentials in plugin configuration.
- Confirm network reachability to the marketplace endpoint (curl/ping).
- Check marketplace service status; retry with backoff if transient.
- Implement offline/grace behavior around the license check using the library's cached lease instead of failing hard.
Example fix
// before
let license = manager.verify()?; // Http bubbles up
// after
let license = match manager.verify() {
Ok(l) => l,
Err(LicenseError::Http(e)) => { tracing::error!("marketplace unreachable: {e}"); manager.cached_lease().ok_or(e)? }
Err(e) => return Err(e),
}; Defensive patterns
Strategy: fallback
Validate before calling
// Pre-flight reachability + config sanity before license verification
assert!(!marketplace_base_url.is_empty(), "marketplace URL configured");
let reachable = reqwest::blocking::get(format!("{base}/health")).is_ok();
if !reachable { return offline_mode(); } Type guard
fn is_http_failure(e: &LicenseError) -> bool {
matches!(e, LicenseError::Http(_))
} Try / catch
match manager.verify() {
Ok(license) => activate(license),
Err(LicenseError::Http(e)) => {
tracing::warn!("marketplace HTTP failure: {e}; using cached lease");
manager.cached_lease().unwrap_or_else(fallback_unlicensed)
}
Err(e) => return Err(e.into()),
} Prevention
- Configure the correct marketplace base URL and credentials up front.
- Implement an offline grace mode backed by the cached license lease.
- Alert on repeated Http errors to catch marketplace outages early.
- Keep plugin-utils updated for marketplace API compatibility.
When it happens
Trigger: Calling license verification functions (e.g. LicenseManager check/verify paths) when the marketplace endpoint is unreachable, returns an error status (HttpError::BadStatus), or its response body cannot be read (HttpError::BodyRead); the HttpError is auto-converted via #[from].
Common situations: Marketplace API downtime or maintenance; wrong marketplace URL/base configuration; invalid or missing API credentials causing 401/403; DNS or firewall blocking the endpoint; offline server attempting an online license check.
Related errors
- Failed to read HTTP response body
- HTTP request failed
- License metadata mismatch
- Plugin-utils has not been initialized (call…
- Failed to query update API
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/ae6cc99494066838.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-plugin-utils/src/license.rs:18
//! License validation, leasing, and offline grace periods.
use crate::{
http::{HttpClient, HttpError},
models::{CheckLicenseResponse, LicenseLease, LicenseStatus, PumpkinMetadata},
};
use std::{
path::{Path, PathBuf},
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")]View on GitHub (pinned to 8d4639e25a)