{"record":{"id":"830920bbda9d1d55","repo":"phacility/phabricator","slug":"err-invalid-certificate","errorCode":"ERR-INVALID-CERTIFICATE","errorMessage":"ERR-INVALID-CERTIFICATE","messagePattern":"ERR-INVALID-CERTIFICATE","errorType":"error_code","errorClass":"ConduitException","httpStatus":null,"severity":"error","filePath":"src/applications/conduit/method/ConduitConnectConduitAPIMethod.php","lineNumber":138,"sourceCode":"            pht(\n              'The request you submitted is signed with a timestamp, but that '.\n              'timestamp is not within %s of the current time. The '.\n              'signed timestamp is %s (%s), and the current server time is '.\n              '%s (%s). This is a difference of %s seconds, but the '.\n              'timestamp must differ from the server time by no more than '.\n              '%s seconds. Your client or server clock may not be set '.\n              'correctly.',\n              phutil_format_relative_time($threshold),\n              $token,\n              date('r', $token),\n              $now,\n              date('r', $now),\n              ($token - $now),\n              $threshold));\n      }\n      $valid = sha1($token.$user->getConduitCertificate());\n      if (!phutil_hashes_are_identical($valid, $signature)) {\n        throw new ConduitException('ERR-INVALID-CERTIFICATE');\n      }\n      $session_key = id(new PhabricatorAuthSessionEngine())->establishSession(\n        PhabricatorAuthSession::TYPE_CONDUIT,\n        $user->getPHID(),\n        $partial = false);\n    } else {\n      throw new ConduitException('ERR-NO-CERTIFICATE');\n    }\n\n    return array(\n      'connectionID'  => mt_rand(),\n      'sessionKey'    => $session_key,\n      'userPHID'      => $user->getPHID(),\n    );\n  }\n\n}\n","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/conduit/method/ConduitConnectConduitAPIMethod.php#L120-L156","documentation":"conduit.connect verifies authSignature against sha1(authToken . user_conduit_certificate) using phutil_hashes_are_identical (a timing-safe comparison). A mismatch means the signature was not computed over the correct token+certificate pair for that user. Timestamp skew is a separate error (ERR-INVALID-TOKEN), so this is purely a wrong-secret or wrong-construction failure.","triggerScenarios":"Client cached an old certificate after it was rotated/regenerated; signature computed over a different concatenation or encoding than sha1(token + certificate); mixing one user's token with another user's certificate.","commonSituations":"Stale ~/.arcrc credentials after an admin regenerated conduit certificates; hand-rolled clients reimplementing the handshake and getting the concatenation order wrong.","solutions":["Re-fetch the certificate: generate a new token, call conduit.getcertificate with it, and use the returned certificate.","Verify the client signs exactly sha1((string)token . certificate) with the same token it sends as authToken.","If problems persist, confirm clocks (skew produces ERR-INVALID-TOKEN, not this error) and that the username matches the certificate owner."],"exampleFix":"# before: stale cached certificate\n$ rm -f ~/.arcrc && arc install-certificate <token>\n# after: arc fetches and stores the current certificate, then\n$ arc call-conduit user.whoami","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  $result = $call->execute();\n} catch (ConduitException $ex) {\n  if ($ex->getMessage() === 'ERR-INVALID-CERTIFICATE') {\n    // Drop cached credentials and re-run the certificate handshake once.\n  }\n}","preventionTips":["Always mint a fresh token and fetch the certificate in the same run; never cache certificates across days.","Compute the signature as exactly sha1((string)$token . $certificate).","Test client clocks separately: skew yields ERR-INVALID-TOKEN, not this error."],"tags":["conduit","auth","certificate","phabricator","php","legacy"],"backgroundTag":"conduit-auth-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}