RocketChat/Rocket.Chat · error · MarketplaceConnectionError
Marketplace_Bad_Marketplace_Connection
Error message
Marketplace_Bad_Marketplace_Connection
What it means
Thrown by fetchMarketplaceApps when the marketplace client fetch to v1/apps throws (network-level failure, not an HTTP error status). The original error is inspected: if it is a CloudOfflineLicenseError (air-gapped/offline license rejecting before any request), it is rethrown as-is; otherwise it is wrapped as MarketplaceConnectionError('Marketplace_Bad_Marketplace_Connection'). HTTP error statuses (4xx/5xx) do NOT hit this path - they are handled downstream.
Source
Thrown at apps/meteor/ee/server/apps/marketplace/fetchMarketplaceApps.ts:167
let request;
try {
request = await Apps.getMarketplaceClient().fetch(`v1/apps`, {
headers,
ignoreSsrfValidation: false,
allowList: settings.get<string>('SSRF_Allowlist'),
params: {
...(endUserID && { endUserID }),
},
});
} catch (error) {
// Offline (air-gapped) licenses reject before any request is made; keep the
// typed error so the REST layer can report the real reason instead of a
// generic connectivity failure.
if (error instanceof CloudOfflineLicenseError) {
throw error;
}
throw new MarketplaceConnectionError('Marketplace_Bad_Marketplace_Connection');
}
if (request.status === 200) {
const response = await request.json();
fetchMarketplaceAppsSchema.parse(response);
return response;
}
const response = await request.json();
Apps.getRocketChatLogger().error({ msg: 'Error fetching marketplace apps', status: request.status, response });
// TODO: Refactor cloud to return a proper error code on unsupported version
if (request.status === 426 && 'errorMsg' in response && response.errorMsg === 'unsupported version') {
throw new MarketplaceUnsupportedVersionError();
}
if (request.status === 400 && response.code === 200) {View on GitHub (pinned to f9d3ec372b)
Solutions
- Verify outbound network access to the marketplace host from the server.
- If behind a proxy, set HTTPS_PROXY / HTTP_PROXY and restart the app.
- If using an offline/air-gapped license intentionally, expect CloudOfflineLicenseError instead and handle marketplace features as unavailable.
- Ensure SSRF_Allowlist (settings) includes the marketplace host if SSRF validation is in play.
- Retry after restoring connectivity.
Defensive patterns
Strategy: retry
Validate before calling
async function canReachMarketplaceHost(): Promise<boolean> {
try {
const res = await Apps.getMarketplaceClient().fetch('v1/categories', { ignoreSsrfValidation: false });
return res.status === 200;
} catch { return false; }
} Type guard
import { CloudOfflineLicenseError } from '../../../../lib/errors/CloudOfflineLicenseError';
const isOfflineLicenseError = (e: unknown): e is CloudOfflineLicenseError =>
e instanceof CloudOfflineLicenseError;
const isConnectionError = (e: unknown): boolean =>
e instanceof Error && e.message === 'Marketplace_Bad_Marketplace_Connection'; Try / catch
import { fetchMarketplaceApps } from './fetchMarketplaceApps';
import { CloudOfflineLicenseError } from '../../../../lib/errors/CloudOfflineLicenseError';
try {
return await fetchMarketplaceApps({ endUserID });
} catch (e) {
if (e instanceof CloudOfflineLicenseError) {
// air-gapped license - marketplace is intentionally unavailable
return [];
}
if (e instanceof Error && e.message === 'Marketplace_Bad_Marketplace_Connection') {
return await retryWithBackoff(() => fetchMarketplaceApps({ endUserID }));
}
throw e;
} Prevention
- Verify egress to the marketplace host and proxy config before relying on marketplace features.
- Add the marketplace host to SSRF_Allowlist if SSRF validation is active.
- Distinguish CloudOfflineLicenseError (intentional offline) from real connectivity failures.
- Retry transient connection errors with exponential backoff.
When it happens
Trigger: Calling fetchMarketplaceApps() while the server has no network route to the marketplace host, DNS resolution fails, the TLS handshake fails, or the request is aborted. The CloudOfflineLicenseError branch fires specifically when the workspace runs an offline/air-gapped license that blocks cloud calls entirely.
Common situations: Air-gapped deployment; egress proxy/firewall blocking the marketplace host; misconfigured SSRF_Allowlist excluding the marketplace; DNS outage; corporate proxy requiring HTTPS_PROXY env not set; offline license used in an environment expected to be online.
Related errors
- Marketplace_Bad_Marketplace_Connection
- App package download failed
- App metadata download failed
- result.error
- Marketplace_Internal_Error
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/f32347a126e24fca.
Report an issue: GitHub.