coder/code-server · error · HttpError
Unauthorized
Error message
Unauthorized
What it means
Thrown by the proxy() handler when the request is not authenticated and the path is not the proxy root (i.e. req.params.path exists and is not '/'). It is an HttpError with status 401 (HttpCode.Unauthorized). For root paths the handler instead redirects unauthenticated users to the login page; this throw is specifically for non-root unauthenticated access.
Source
Thrown at src/node/routes/pathProxy.ts:44
res: Response,
opts?: {
passthroughPath?: boolean
proxyBasePath?: string
},
): Promise<void> {
ensureProxyEnabled(req)
if (req.method === "OPTIONS" && req.args["skip-auth-preflight"]) {
// Allow preflight requests with `skip-auth-preflight` flag
} else if (!(await authenticated(req))) {
// If visiting the root (/:port only) redirect to the login page.
if (!req.params.path || req.params.path === "/") {
const to = self(req)
return redirect(req, res, "login", {
to: to !== "/" ? to : undefined,
})
}
throw new HttpError("Unauthorized", HttpCode.Unauthorized)
}
// The base is used for rewriting (redirects, target).
if (!opts?.passthroughPath) {
;(req as any).base = req.path.split(path.sep).slice(0, 3).join(path.sep)
}
_proxy.web(req, res, {
ignorePath: true,
target: getProxyTarget(req, opts),
})
}
export async function wsProxy(
req: WebsocketRequest,
opts?: {
passthroughPath?: boolean
proxyBasePath?: stringView on GitHub (pinned to 51f90a376b)
Solutions
- Authenticate first: log in via /login to obtain a valid session cookie, then retry the proxied request.
- For CORS preflight requests that must pass without auth, start code-server with --auth none or set the skip-auth-preflight arg (only if you understand the security implications).
- Ensure the reverse proxy forwards the Cookie header and Host/origin so authenticated() validates correctly.
- Confirm the cookie name matches req.cookieSessionName and that the cookie domain/path is correct.
Example fix
// client: log in first, then call the proxied port
await loginAndGetCookie()
await fetch('/proxy/3000/api/items', { headers: { Cookie: sessionCookie } }) Defensive patterns
Strategy: try-catch
Validate before calling
// Before calling the proxy, ensure the session cookie is present.
function hasSessionCookie(name: string): boolean {
return document.cookie.split('; ').some(c => c.startsWith(name + '='))
}
if (!hasSessionCookie(cookieSessionName)) await redirectToLogin() Type guard
// Server-side helper (mirrors authenticated(req))
async function isAuthenticated(req: Request): Promise<boolean> {
return authenticated(req)
} Try / catch
// Client: expect a 401 and re-authenticate.
try {
const res = await fetch(`/proxy/${port}${path}`, { headers: { Cookie } })
if (res.status === 401) { await login(); return retry() }
} catch (e) { /* network error */ } Prevention
- Always log in before issuing proxied requests.
- Forward the Cookie header through any reverse proxy.
- Use skip-auth-preflight only after a security review.
- Handle 401 by redirecting to /login with a 'to' param.
When it happens
Trigger: A request to /:port/<some-path> where the caller has no valid session cookie, the cookie expired, or skip-auth-preflight is not set so even OPTIONS preflight requests are subject to auth. Also when authenticated(req) returns false due to a missing/invalid password cookie.
Common situations: Session cookie expired; user opened a proxied resource link directly without being logged in; a third-party tool hitting the proxy endpoint without sending credentials; CSRF/auth middleware rejecting the cookie; reverse proxy stripping cookies.
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/72c21f28025092f4.
Report an issue: GitHub.