{"record":{"id":"72c21f28025092f4","repo":"coder/code-server","slug":"unauthorized-72c21f","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":"HttpError","httpStatus":401,"severity":"error","filePath":"src/node/routes/pathProxy.ts","lineNumber":44,"sourceCode":"  res: Response,\n  opts?: {\n    passthroughPath?: boolean\n    proxyBasePath?: string\n  },\n): Promise<void> {\n  ensureProxyEnabled(req)\n\n  if (req.method === \"OPTIONS\" && req.args[\"skip-auth-preflight\"]) {\n    // Allow preflight requests with `skip-auth-preflight` flag\n  } else if (!(await authenticated(req))) {\n    // If visiting the root (/:port only) redirect to the login page.\n    if (!req.params.path || req.params.path === \"/\") {\n      const to = self(req)\n      return redirect(req, res, \"login\", {\n        to: to !== \"/\" ? to : undefined,\n      })\n    }\n    throw new HttpError(\"Unauthorized\", HttpCode.Unauthorized)\n  }\n\n  // The base is used for rewriting (redirects, target).\n  if (!opts?.passthroughPath) {\n    ;(req as any).base = req.path.split(path.sep).slice(0, 3).join(path.sep)\n  }\n\n  _proxy.web(req, res, {\n    ignorePath: true,\n    target: getProxyTarget(req, opts),\n  })\n}\n\nexport async function wsProxy(\n  req: WebsocketRequest,\n  opts?: {\n    passthroughPath?: boolean\n    proxyBasePath?: string","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/coder/code-server/blob/51f90a376b42e217b38937410fe2855e0c1db87e/src/node/routes/pathProxy.ts#L26-L62","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// client: log in first, then call the proxied port\nawait loginAndGetCookie()\nawait fetch('/proxy/3000/api/items', { headers: { Cookie: sessionCookie } })","handlingStrategy":"try-catch","validationCode":"// Before calling the proxy, ensure the session cookie is present.\nfunction hasSessionCookie(name: string): boolean {\n  return document.cookie.split('; ').some(c => c.startsWith(name + '='))\n}\nif (!hasSessionCookie(cookieSessionName)) await redirectToLogin()","typeGuard":"// Server-side helper (mirrors authenticated(req))\nasync function isAuthenticated(req: Request): Promise<boolean> {\n  return authenticated(req)\n}","tryCatchPattern":"// Client: expect a 401 and re-authenticate.\ntry {\n  const res = await fetch(`/proxy/${port}${path}`, { headers: { Cookie } })\n  if (res.status === 401) { await login(); return retry() }\n} catch (e) { /* network error */ }","preventionTips":["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."],"tags":["proxy","authentication","authorization","http","unauthorized"],"backgroundTag":null,"analyzedSha":"51f90a376b42e217b38937410fe2855e0c1db87e","analyzedAt":"2026-08-12T11:27:34.273Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}