coder/code-server · error · HttpError
Unauthorized
Error message
Unauthorized
What it means
ensureAuthenticated (http.ts:107) is the auth middleware for protected routes. It awaits authenticated(req), which validates the session cookie against the configured auth method; if validation fails it throws HttpError 401 Unauthorized. This is the primary gate for non-login pages when auth is enabled.
Source
Thrown at src/node/http.ts:107
/**
* 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,
_?: express.Response,
next?: express.NextFunction,
): Promise<void> => {
const isAuthenticated = await authenticated(req)
if (!isAuthenticated) {
throw new HttpError("Unauthorized", HttpCode.Unauthorized)
}
if (next) {
next()
}
}
/**
* Return true if authenticated via cookies.
*/
export const authenticated = async (req: express.Request): Promise<boolean> => {
switch (req.args.auth) {
case AuthType.None: {
return true
}
case AuthType.Password: {
// The password is stored in the cookie after being hashed.
const hashedPasswordFromArgs = req.args["hashed-password"]
const passwordMethod = getPasswordMethod(hashedPasswordFromArgs)View on GitHub (pinned to 51f90a376b)
Solutions
- Redirect the user to /login to obtain a fresh session cookie
- Ensure PASSWORD/HASHED_PASSWORD is stable across restarts so the cookie stays valid
- Check that the system clock is correct (significant skew can invalidate cookies)
Example fix
// before: hitting a protected route with no/expired cookie -> 401
// after: redirect to login, then re-request
fetch('/login', { method: 'POST', body: 'password=...' })
.then(() => fetch('/api/protected')) Defensive patterns
Strategy: try-catch
Validate before calling
// Client-side: check auth before protected calls
async function isAuthenticated(): Promise<boolean> {
const r = await fetch("/api/status")
return r.ok
}
if (!await isAuthenticated()) window.location.href = "/login" Type guard
import { HttpError, HttpCode } from "../../common/http"
function isUnauthorizedError(e: unknown): boolean {
return e instanceof HttpError && e.status === HttpCode.Unauthorized
} Try / catch
try {
await ensureAuthenticated(req, res, next)
} catch (e) {
if (e instanceof HttpError && e.status === HttpCode.Unauthorized) {
redirect(req, res, "login", { to: req.originalUrl })
} else throw e
} Prevention
- Keep PASSWORD/HASHED_PASSWORD stable across restarts to preserve cookies
- Handle 401 in clients by redirecting to /login
- Avoid rotating the cookie signing key unnecessarily
When it happens
Trigger: Any request to a protected route without a valid session cookie: expired cookie, never logged in, cookie cleared, or session invalidated by a restart with a new COOKIE_KEY.
Common situations: Sessions expiring mid-work; restarting code-server in a way that rotates the signing key; browsers with aggressive cookie cleanup; clock skew breaking cookie expiry.
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/a4187a38cf8d9a7e.
Report an issue: GitHub.