{"record":{"id":"175027af24631987","repo":"phacility/phabricator","slug":"err-invalid-auth","errorCode":"ERR-INVALID-AUTH","errorMessage":"ERR-INVALID-AUTH","messagePattern":"ERR-INVALID-AUTH","errorType":"error_code","errorClass":"ConduitException","httpStatus":null,"severity":"error","filePath":"src/applications/conduit/call/ConduitCall.php","lineNumber":108,"sourceCode":"\n  private function executeMethod() {\n    $user = $this->getUser();\n    if (!$user) {\n      $user = new PhabricatorUser();\n    }\n\n    $this->request->setUser($user);\n\n    if (!$this->shouldRequireAuthentication()) {\n      // No auth requirement here.\n    } else {\n\n      $allow_public = $this->handler->shouldAllowPublic() &&\n                      PhabricatorEnv::getEnvConfig('policy.allow-public');\n      if (!$allow_public) {\n        if (!$user->isLoggedIn() && !$user->isOmnipotent()) {\n          // TODO: As per below, this should get centralized and cleaned up.\n          throw new ConduitException('ERR-INVALID-AUTH');\n        }\n      }\n\n      // TODO: This would be slightly cleaner by just using a Query, but the\n      // Conduit auth workflow requires the Call and User be built separately.\n      // Just do it this way for the moment.\n      $application = $this->handler->getApplication();\n      if ($application) {\n        $can_view = PhabricatorPolicyFilter::hasCapability(\n          $user,\n          $application,\n          PhabricatorPolicyCapability::CAN_VIEW);\n\n        if (!$can_view) {\n          throw new ConduitException(\n            pht(\n              'You do not have access to the application which provides this '.\n              'API method.'));","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/conduit/call/ConduitCall.php#L90-L126","documentation":"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.","triggerScenarios":"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","commonSituations":"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.","solutions":["Supply credentials: create an API token in Settings -> Conduit API Tokens and send it (arc uses it automatically; raw HTTP uses the Authorization header)","If the endpoint is meant to be public, implement shouldAllowPublic() on the method AND set 'policy.allow-public' to true in instance config","For expired sessions, re-authenticate the client and retry with a fresh token"],"exampleFix":"# before\ncurl https://phabricator.example.com/api/user.whoami\n\n# after\ncurl -H 'Authorization: Bearer api-xxxxxxxxxxxxxxxx' \\\n  https://phabricator.example.com/api/user.whoami","handlingStrategy":"validation","validationCode":"if (!$conduit_token) {\n  throw new Exception(\n    'Conduit token missing: create one under Settings -> Conduit API Tokens.');\n}\n// Optional: verify the token works with a cheap call before the real one.\ntry {\n  $conduit->callMethod('user.whoami', array());\n} catch (ConduitException $ex) {\n  if ($ex->getMessage() === 'ERR-INVALID-AUTH') {\n    throw new Exception('Conduit token invalid or expired; reissue it.');\n  }\n  throw $ex;\n}","typeGuard":null,"tryCatchPattern":"try {\n  $result = $conduit->callMethod($method, $params);\n} catch (ConduitException $ex) {\n  if ($ex->getMessage() === 'ERR-INVALID-AUTH') {\n    // Re-prompt for credentials / refresh the API token, then retry once.\n    $conduit->refreshToken();\n    $result = $conduit->callMethod($method, $params);\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Store the API token in config/secret storage, never inline in scripts; fail fast when it is absent","Call user.whoami at script start to detect dead tokens before real work begins","If endpoints must be anonymous, set both shouldAllowPublic() on the method and policy.allow-public in config"],"tags":["phabricator","conduit","authentication","api-token","policy"],"backgroundTag":"missing-authentication-credentials","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}