RocketChat/Rocket.Chat · error · Meteor.Error

error-endpoint-disabled

error-endpoint-disabled

Error message

This endpoint is disabled

What it means

GET /api/v1/shield.svg renders unauthenticated SVG badges (online status, user count, channel info). misc.ts:222 gates the whole route on the setting API_Enable_Shields; when it is false, every request - regardless of parameters - fails with error-endpoint-disabled. In this codebase the setting defaults to true (apps/meteor/server/settings/general.ts:13), so seeing this error means an admin explicitly disabled it, often because the route is public and exposes presence/metadata.

Solutions

  1. Re-enable shields: Administration -> General -> REST API -> Enable Shields, or POST /api/v1/settings/API_Enable_Shields {"value": true} with an admin token
  2. After enabling, confirm the requested badge type passes API_Shield_Types (the next gate, error-shield-disabled)
  3. If shields must stay off, host the badge content elsewhere - there is no auth path for this route
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const svg = await fetch(`${server}/api/v1/shield.svg?type=online&name=${name}`);
  if (!svg.ok) throw await svg.json();
  return svg;
} catch (err) {
  if (err?.error === 'error-endpoint-disabled') {
    return staticFallbackBadge(); // shields disabled on this workspace - degrade gracefully
  }
  throw err;
}

Prevention

When it happens

Trigger: Embedding <img src="https://chat.example.com/api/v1/shield.svg?type=online&name=user"> on a workspace where API_Enable_Shields was switched off.

Common situations: Badges embedded in READMEs or status pages stop rendering after an admin hardens public API exposure; new badge integrations added to a workspace where shields were disabled years ago.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@2a7de45707 (2026-08-18). Data as JSON: /api/errors/94055a6afcf396a1. Report an issue: GitHub.

Appendix: source

Thrown at apps/meteor/server/api/v1/misc.ts:223

API.v1.get(
	'shield.svg',
	{
		authRequired: false,
		rateLimiterOptions: {
			numRequestsAllowed: 60,
			intervalTimeInMS: 60000,
		},
		query: isShieldSvgProps,
		response: {
			200: shieldSvgResponseSchema,
			400: validateBadRequestErrorResponse,
		},
	},
	async function action() {
		const { type, icon } = this.queryParams;
		let { channel, name } = this.queryParams;
		if (!settings.get('API_Enable_Shields')) {
			throw new Meteor.Error('error-endpoint-disabled', 'This endpoint is disabled', {
				route: '/api/v1/shield.svg',
			});
		}

		const types = settings.get<string>('API_Shield_Types');
		if (
			type &&
			types !== '*' &&
			!types
				.split(',')
				.map((t: string) => t.trim())
				.includes(type)
		) {
			throw new Meteor.Error('error-shield-disabled', 'This shield type is disabled', {
				route: '/api/v1/shield.svg',
			});
		}
		const hideIcon = icon === 'false';

View on GitHub (pinned to 2a7de45707)