{"record":{"id":"a71aa65d58d994ee","repo":"coder/code-server","slug":"forbidden","errorCode":null,"errorMessage":"Forbidden","messagePattern":"Forbidden","errorType":"http","errorClass":"HttpError","httpStatus":403,"severity":"error","filePath":"src/node/http.ts","lineNumber":83,"sourceCode":"): string => {\n  const serverOptions: ClientConfiguration = {\n    ...createClientConfiguration(req),\n    ...extraOpts,\n  }\n\n  return content\n    .replace(/{{TO}}/g, (typeof req.query.to === \"string\" && escapeHtml(req.query.to)) || \"/\")\n    .replace(/{{BASE}}/g, serverOptions.base)\n    .replace(/{{CS_STATIC_BASE}}/g, serverOptions.csStaticBase)\n    .replace(\"{{OPTIONS}}\", () => escapeJSON(serverOptions))\n}\n\n/**\n * Throw an error if proxy is not enabled. Call `next` if provided.\n */\nexport const ensureProxyEnabled = (req: express.Request, _?: express.Response, next?: express.NextFunction): void => {\n  if (!proxyEnabled(req)) {\n    throw new HttpError(\"Forbidden\", HttpCode.Forbidden)\n  }\n  if (next) {\n    next()\n  }\n}\n\n/**\n * Return true if proxy is enabled.\n */\nexport const proxyEnabled = (req: express.Request): boolean => {\n  return !req.args[\"disable-proxy\"]\n}\n\n/**\n * Throw an error if not authorized. Call `next` if provided.\n */\nexport const ensureAuthenticated = async (\n  req: express.Request,","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/coder/code-server/blob/51f90a376b42e217b38937410fe2855e0c1db87e/src/node/http.ts#L65-L101","documentation":"ensureProxyEnabled (http.ts:83) is Express middleware guarding the /proxy subdomain proxy routes. If req.args['disable-proxy'] is truthy (set via --disable-proxy), it throws an HttpError with status 403 Forbidden. This prevents access to the proxy feature when an operator has explicitly turned it off.","triggerScenarios":"An HTTP request to a /proxy/<port>/... path (or subdomain proxy) while code-server was started with `--disable-proxy`, or any route wired through ensureProxyEnabled when the proxy is disabled.","commonSituations":"Hardening a deployment with --disable-proxy and then a user/app still hitting proxy URLs; leftover bookmarks or extensions that route through the proxy.","solutions":["Restart code-server without --disable-proxy if the proxy is needed","Update the client/extension to use direct ports instead of the code-server proxy","If 403 is expected, surface a clearer message to the end user (the proxy is intentionally off)"],"exampleFix":"# before\ncode-server --disable-proxy\n# client hits https://host/proxy/3000/...\n\n# after\ncode-server\n# proxy routes are enabled","handlingStrategy":"type-guard","validationCode":"// Before depending on the proxy, check the runtime args\nfunction proxyIsEnabled(args: { \"disable-proxy\"?: boolean }): boolean {\n  return !args[\"disable-proxy\"]\n}\nif (!proxyIsEnabled(args)) {\n  throw new Error(\"Proxy is disabled; cannot route to /proxy/\")\n}","typeGuard":"import { HttpError, HttpCode } from \"../../common/http\"\nfunction isForbiddenProxyError(e: unknown): boolean {\n  return e instanceof HttpError && e.status === HttpCode.Forbidden && e.message === \"Forbidden\"\n}","tryCatchPattern":"try {\n  await ensureProxyEnabled(req, res, next)\n} catch (e) {\n  if (e instanceof HttpError && e.status === HttpCode.Forbidden) {\n    res.status(403).send(\"Proxy is disabled on this server\")\n  } else throw e\n}","preventionTips":["Expose proxyEnabled status to clients so they can avoid proxy URLs when off","Document --disable-proxy implications for users","Gate proxy-dependent features behind a config check in the UI"],"tags":["http","proxy","middleware","security","forbidden"],"backgroundTag":null,"analyzedSha":"51f90a376b42e217b38937410fe2855e0c1db87e","analyzedAt":"2026-08-12T11:27:34.273Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}