pnpm/pnpm · error · LogoutFailedError

LOGOUT_FAILED

LOGOUT_FAILED

Error message

Failed to log out of ${registry}. The registry rejected the token revocation request, and the token was not found in ${configPath}. The token may be configured in .npmrc or another config file and must be removed manually, and may still need to be revoked on the registry.

What it means

logout attempts two things: revoking the token on the registry and deleting it from pnpm's auth.ini. When the registry rejected the revocation AND the token key was not present in auth.ini, nothing could be done automatically, so LOGOUT_FAILED reports both facts and directs manual cleanup — the token likely lives in `.npmrc` or another config file and may still be valid on the registry.

Source

Thrown at pnpm11/auth/commands/src/logout.ts:133

  if (!token) {
    throw new LogoutNotLoggedInError(registry)
  }

  const revokedOnRegistry = await tryRevokeToken({ context, opts, registry, token })

  const configPath = path.join(opts.configDir, 'auth.ini')
  const authIniSettings = await safeReadIniFile(readIniFile, configPath) as Record<string, unknown>

  if (tokenKey in authIniSettings) {
    await removeTokenFromAuthIni({ context, configPath, authIniSettings, tokenKey })
  } else if (revokedOnRegistry) {
    globalWarn(
      `The auth token for ${registry} was not found in ${configPath}. ` +
      'It may be configured in .npmrc or another config file. ' +
      'The token was revoked on the registry but must be removed manually from that config file.'
    )
  } else {
    throw new LogoutFailedError(registry, configPath)
  }

  return `Logged out of ${registry}`
}

interface TryRevokeTokenParams {
  context: Pick<LogoutContext, 'fetch' | 'globalInfo'>
  opts: Pick<LogoutCommandOptions, 'fetchRetries' | 'fetchRetryFactor' | 'fetchRetryMaxtimeout' | 'fetchRetryMintimeout' | 'fetchTimeout'>
  registry: string
  token: string
}

async function tryRevokeToken ({
  context: { fetch, globalInfo },
  opts,
  registry,
  token,
}: TryRevokeTokenParams): Promise<boolean> {

View on GitHub (pinned to 5b11d3a15b)

Solutions

  1. Remove the token manually from wherever it lives: search `~/.npmrc`, project `.npmrc`, and pnpm config files for `:_authToken` lines under that registry and delete them
  2. Revoke the token separately via the registry's API or dashboard if it supports it
  3. If the revocation failure looked transient (5xx, timeout), fix connectivity and rerun `pnpm logout` before doing manual cleanup
  4. Verify with `pnpm whoami` afterwards that you are actually logged out

Example fix

# before
pnpm logout  # token in ~/.npmrc, revoke endpoint failed

# after
# 1) locate and delete the line:
#   grep -n '_authToken' ~/.npmrc   ->  delete the matching :_authToken line
# 2) revoke via registry dashboard if supported
pnpm whoami  # should now report not logged in
Defensive patterns

Strategy: validation

Validate before calling

// before logout, locate where the token actually lives
import { existsSync, readFileSync } from 'node:fs'
import os from 'node:os'
import path from 'node:path'

const files = [path.join(os.homedir(), '.npmrc'), '.npmrc', path.join(configDir, 'auth.ini')]
const known = files.filter((f) => existsSync(f) && readFileSync(f, 'utf8').includes('_authToken'))
if (known.length === 0) {
  throw new Error('no token configured anywhere — logout will fail with NOT_LOGGED_IN')
}
if (!known.some((f) => f.endsWith('auth.ini'))) {
  console.warn('token is outside auth.ini; if revocation fails, removal will be manual')
}

Prevention

When it happens

Trigger: `pnpm logout` where the token is configured in `~/.npmrc` (not pnpm's auth.ini) and the revocation request fails — network error, 4xx/5xx from the registry, or an unimplemented revoke endpoint.

Common situations: Tokens set manually via `npm config set` or shared `.npmrc` files; enterprise registries without a revocation endpoint; tokens already revoked out of band; mixed npm/pnpm config setups.

Related errors


AI-assisted analysis of pnpm/pnpm@5b11d3a15b (2026-08-16). Data as JSON: /api/errors/ac1e7bedb6954010. Report an issue: GitHub.