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

  1. Redirect the user to /login to obtain a fresh session cookie
  2. Ensure PASSWORD/HASHED_PASSWORD is stable across restarts so the cookie stays valid
  3. 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

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

Related errors


AI-assisted analysis of coder/code-server@51f90a376b (2026-08-12). Data as JSON: /api/errors/a4187a38cf8d9a7e. Report an issue: GitHub.