actualbudget/actual · error · Error

Authentication required. Set --password/--session-token, ACT

Error message

Authentication required. Set --password/--session-token, ACTUAL_PASSWORD/ACTUAL_SESSION_TOKEN env var, or password/sessionToken in config file.

What it means

resolveConfig requires some form of authentication: a password or a session token, from CLI flags, environment variables, or the config file. When neither is present after merging all sources, it throws this error. A server URL alone is not enough to connect.

Source

Thrown at packages/cli/src/config.ts:187

  const dataDir =
    cliOpts.dataDir ??
    process.env.ACTUAL_DATA_DIR ??
    fileConfig.dataDir ??
    join(homedir(), '.actual-cli', 'data');

  const encryptionPassword =
    cliOpts.encryptionPassword ??
    process.env.ACTUAL_ENCRYPTION_PASSWORD ??
    fileConfig.encryptionPassword;

  if (!serverUrl) {
    throw new Error(
      'Server URL is required. Set --server-url, ACTUAL_SERVER_URL env var, or serverUrl in config file.',
    );
  }

  if (!password && !sessionToken) {
    throw new Error(
      'Authentication required. Set --password/--session-token, ACTUAL_PASSWORD/ACTUAL_SESSION_TOKEN env var, or password/sessionToken in config file.',
    );
  }

  const cacheTtl = validateNonNegativeInt(
    cliOpts.cacheTtl ??
      parseNonNegativeIntEnv(
        process.env.ACTUAL_CACHE_TTL,
        'ACTUAL_CACHE_TTL',
      ) ??
      fileConfig.cacheTtl ??
      60,
    'cacheTtl',
  );

  const lockTimeout = validateNonNegativeInt(
    cliOpts.lockTimeout ??
      parseNonNegativeIntEnv(

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Provide --password or --session-token on the command line.
  2. Export ACTUAL_PASSWORD or ACTUAL_SESSION_TOKEN in the environment.
  3. Add password or sessionToken to the config file (prefer sessionToken to avoid storing plaintext passwords).
  4. Ensure your .env / dotenv file is actually loaded by the shell or CI job.

Example fix

// before
actual-cli budgets --server-url=https://actual.example.com
// after
actual-cli budgets --server-url=https://actual.example.com --password "$ACTUAL_PASSWORD"
Defensive patterns

Strategy: validation

Validate before calling

const hasAuth = Boolean(
  cliOpts.password ?? process.env.ACTUAL_PASSWORD ?? fileConfig.password ??
  cliOpts.sessionToken ?? process.env.ACTUAL_SESSION_TOKEN ?? fileConfig.sessionToken,
);
if (!hasAuth) throw new Error('Authentication required before invoking the CLI.');

Type guard

function hasCredentials(c: { password?: string; sessionToken?: string }): c is typeof c & ({ password: string } | { sessionToken: string }) {
  return Boolean(c.password || c.sessionToken);
}

Try / catch

try {
  await run(cmdOpts);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Authentication required')) {
    console.error('Provide ACTUAL_PASSWORD or ACTUAL_SESSION_TOKEN (or config file equivalents).');
    process.exit(1);
  }
  throw err;
}

Prevention

When it happens

Trigger: Running a command with --server-url set but no --password/--session-token, no ACTUAL_PASSWORD/ACTUAL_SESSION_TOKEN env vars, and no password/sessionToken in the config file.

Common situations: Setting only ACTUAL_SERVER_URL in CI; password stored in a dotenv file that is not loaded; typos like ACTUAL_PASSWORDS or using the sync-server's own env names incorrectly.

Understand the failure class

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/6a9a5eb83ac07e4a. Report an issue: GitHub.