{"record":{"id":"94055a6afcf396a1","repo":"RocketChat/Rocket.Chat","slug":"error-endpoint-disabled-94055a","errorCode":"error-endpoint-disabled","errorMessage":"This endpoint is disabled","messagePattern":"This endpoint is disabled","errorType":"exception","errorClass":"Meteor.Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/misc.ts","lineNumber":223,"sourceCode":"API.v1.get(\n\t'shield.svg',\n\t{\n\t\tauthRequired: false,\n\t\trateLimiterOptions: {\n\t\t\tnumRequestsAllowed: 60,\n\t\t\tintervalTimeInMS: 60000,\n\t\t},\n\t\tquery: isShieldSvgProps,\n\t\tresponse: {\n\t\t\t200: shieldSvgResponseSchema,\n\t\t\t400: validateBadRequestErrorResponse,\n\t\t},\n\t},\n\tasync function action() {\n\t\tconst { type, icon } = this.queryParams;\n\t\tlet { channel, name } = this.queryParams;\n\t\tif (!settings.get('API_Enable_Shields')) {\n\t\t\tthrow new Meteor.Error('error-endpoint-disabled', 'This endpoint is disabled', {\n\t\t\t\troute: '/api/v1/shield.svg',\n\t\t\t});\n\t\t}\n\n\t\tconst types = settings.get<string>('API_Shield_Types');\n\t\tif (\n\t\t\ttype &&\n\t\t\ttypes !== '*' &&\n\t\t\t!types\n\t\t\t\t.split(',')\n\t\t\t\t.map((t: string) => t.trim())\n\t\t\t\t.includes(type)\n\t\t) {\n\t\t\tthrow new Meteor.Error('error-shield-disabled', 'This shield type is disabled', {\n\t\t\t\troute: '/api/v1/shield.svg',\n\t\t\t});\n\t\t}\n\t\tconst hideIcon = icon === 'false';","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/2a7de457074cbb4d4373fbd9a4e5bea292c9c764/apps/meteor/server/api/v1/misc.ts#L205-L241","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-enable shields: Administration -> General -> REST API -> Enable Shields, or POST /api/v1/settings/API_Enable_Shields {\"value\": true} with an admin token","After enabling, confirm the requested badge type passes API_Shield_Types (the next gate, error-shield-disabled)","If shields must stay off, host the badge content elsewhere - there is no auth path for this route"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const svg = await fetch(`${server}/api/v1/shield.svg?type=online&name=${name}`);\n  if (!svg.ok) throw await svg.json();\n  return svg;\n} catch (err) {\n  if (err?.error === 'error-endpoint-disabled') {\n    return staticFallbackBadge(); // shields disabled on this workspace - degrade gracefully\n  }\n  throw err;\n}","preventionTips":["Always ship a fallback image for embedded badges - they depend on remote admin settings","Document that shield.svg is public and can be disabled by policy at any time","Never poll shield.svg; cache the SVG client-side"],"tags":["rest-api","shields","settings","badge","public-route","disabled-feature"],"backgroundTag":"endpoint-disabled-by-config","analyzedSha":"2a7de457074cbb4d4373fbd9a4e5bea292c9c764","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}