coder/code-server · error · HttpError
Forbidden
Error message
Forbidden
What it means
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.
Source
Thrown at src/node/http.ts:83
): string => {
const serverOptions: ClientConfiguration = {
...createClientConfiguration(req),
...extraOpts,
}
return content
.replace(/{{TO}}/g, (typeof req.query.to === "string" && escapeHtml(req.query.to)) || "/")
.replace(/{{BASE}}/g, serverOptions.base)
.replace(/{{CS_STATIC_BASE}}/g, serverOptions.csStaticBase)
.replace("{{OPTIONS}}", () => escapeJSON(serverOptions))
}
/**
* Throw an error if proxy is not enabled. Call `next` if provided.
*/
export const ensureProxyEnabled = (req: express.Request, _?: express.Response, next?: express.NextFunction): void => {
if (!proxyEnabled(req)) {
throw new HttpError("Forbidden", HttpCode.Forbidden)
}
if (next) {
next()
}
}
/**
* Return true if proxy is enabled.
*/
export const proxyEnabled = (req: express.Request): boolean => {
return !req.args["disable-proxy"]
}
/**
* Throw an error if not authorized. Call `next` if provided.
*/
export const ensureAuthenticated = async (
req: express.Request,View on GitHub (pinned to 51f90a376b)
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)
Example fix
# before code-server --disable-proxy # client hits https://host/proxy/3000/... # after code-server # proxy routes are enabled
Defensive patterns
Strategy: type-guard
Validate before calling
// Before depending on the proxy, check the runtime args
function proxyIsEnabled(args: { "disable-proxy"?: boolean }): boolean {
return !args["disable-proxy"]
}
if (!proxyIsEnabled(args)) {
throw new Error("Proxy is disabled; cannot route to /proxy/")
} Type guard
import { HttpError, HttpCode } from "../../common/http"
function isForbiddenProxyError(e: unknown): boolean {
return e instanceof HttpError && e.status === HttpCode.Forbidden && e.message === "Forbidden"
} Try / catch
try {
await ensureProxyEnabled(req, res, next)
} catch (e) {
if (e instanceof HttpError && e.status === HttpCode.Forbidden) {
res.status(403).send("Proxy is disabled on this server")
} else throw e
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Hardening a deployment with --disable-proxy and then a user/app still hitting proxy URLs; leftover bookmarks or extensions that route through the proxy.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of coder/code-server@51f90a376b (2026-08-12).
Data as JSON: /api/errors/a71aa65d58d994ee.
Report an issue: GitHub.