phacility/phabricator · error · ConduitException

ERR-INVALID-AUTH

ERR-INVALID-AUTH

Error message

ERR-INVALID-AUTH

What it means

Conduit methods require authentication by default; the call throws ERR-INVALID-AUTH when the method is not exempt, the user is neither logged in nor omnipotent, and the method does not permit anonymous access (shouldAllowPublic() false or policy.allow-public disabled in config). It is an authentication failure — the identity was never established, distinct from a later policy denial.

Source

Thrown at src/applications/conduit/call/ConduitCall.php:108

  private function executeMethod() {
    $user = $this->getUser();
    if (!$user) {
      $user = new PhabricatorUser();
    }

    $this->request->setUser($user);

    if (!$this->shouldRequireAuthentication()) {
      // No auth requirement here.
    } else {

      $allow_public = $this->handler->shouldAllowPublic() &&
                      PhabricatorEnv::getEnvConfig('policy.allow-public');
      if (!$allow_public) {
        if (!$user->isLoggedIn() && !$user->isOmnipotent()) {
          // TODO: As per below, this should get centralized and cleaned up.
          throw new ConduitException('ERR-INVALID-AUTH');
        }
      }

      // TODO: This would be slightly cleaner by just using a Query, but the
      // Conduit auth workflow requires the Call and User be built separately.
      // Just do it this way for the moment.
      $application = $this->handler->getApplication();
      if ($application) {
        $can_view = PhabricatorPolicyFilter::hasCapability(
          $user,
          $application,
          PhabricatorPolicyCapability::CAN_VIEW);

        if (!$can_view) {
          throw new ConduitException(
            pht(
              'You do not have access to the application which provides this '.
              'API method.'));

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Supply credentials: create an API token in Settings -> Conduit API Tokens and send it (arc uses it automatically; raw HTTP uses the Authorization header)
  2. If the endpoint is meant to be public, implement shouldAllowPublic() on the method AND set 'policy.allow-public' to true in instance config
  3. For expired sessions, re-authenticate the client and retry with a fresh token

Example fix

# before
curl https://phabricator.example.com/api/user.whoami

# after
curl -H 'Authorization: Bearer api-xxxxxxxxxxxxxxxx' \
  https://phabricator.example.com/api/user.whoami
Defensive patterns

Strategy: validation

Validate before calling

if (!$conduit_token) {
  throw new Exception(
    'Conduit token missing: create one under Settings -> Conduit API Tokens.');
}
// Optional: verify the token works with a cheap call before the real one.
try {
  $conduit->callMethod('user.whoami', array());
} catch (ConduitException $ex) {
  if ($ex->getMessage() === 'ERR-INVALID-AUTH') {
    throw new Exception('Conduit token invalid or expired; reissue it.');
  }
  throw $ex;
}

Try / catch

try {
  $result = $conduit->callMethod($method, $params);
} catch (ConduitException $ex) {
  if ($ex->getMessage() === 'ERR-INVALID-AUTH') {
    // Re-prompt for credentials / refresh the API token, then retry once.
    $conduit->refreshToken();
    $result = $conduit->callMethod($method, $params);
  } else {
    throw $ex;
  }
}

Prevention

When it happens

Trigger: Calling a conduit method with no credentials at all; Using a session cookie/token that expired, so the effective user is anonymous; Calling a shouldAllowPublic() method while 'policy.allow-public' is false in instance config; Scripts that assume CLI context is authenticated but construct the call with a bare PhabricatorUser

Common situations: Cron jobs or CI scripts that lost their stored API token; curl calls to /api/<method> without an Authorization header; tokens revoked under Settings -> Conduit API Tokens; policy.allow-public toggled off during a security review, breaking previously anonymous endpoints.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/175027af24631987. Report an issue: GitHub.