{"record":{"id":"a3d0e9b5b4395f4d","repo":"phacility/phabricator","slug":"this-request-improperly-specifies-an-mfa-challenge","errorCode":null,"errorMessage":"This request improperly specifies an MFA challenge token (\"%s\") multiple times and can not be processed.","messagePattern":"This request improperly specifies an MFA challenge token \\(\"(.+?)\"\\) multiple times and can not be processed\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/auth/storage/PhabricatorAuthChallenge.php","lineNumber":86,"sourceCode":"\n      if (!strlen($token_element)) {\n        continue;\n      }\n\n      // NOTE: This error message is intentionally not printing the token to\n      // avoid disclosing it. As a result, it isn't terribly useful, but no\n      // normal user should ever end up here.\n      if (!preg_match('/^[^:]+:/', $token_element)) {\n        throw new Exception(\n          pht(\n            'This request included an improperly formatted MFA challenge '.\n            'token and can not be processed.'));\n      }\n\n      list($phid, $token) = explode(':', $token_element, 2);\n\n      if (isset($token_map[$phid])) {\n        throw new Exception(\n          pht(\n            'This request improperly specifies an MFA challenge token (\"%s\") '.\n            'multiple times and can not be processed.',\n            $phid));\n      }\n\n      $token_map[$phid] = new PhutilOpaqueEnvelope($token);\n    }\n\n    $challenges = mpull($challenges, null, 'getPHID');\n\n    $now = PhabricatorTime::getNow();\n    foreach ($challenges as $challenge_phid => $challenge) {\n      // If the response window has expired, don't attach the token.\n      if ($challenge->getResponseTTL() < $now) {\n        continue;\n      }\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/auth/storage/PhabricatorAuthChallenge.php#L68-L104","documentation":"The same parser in PhabricatorAuthChallenge::newChallengeResponsesFromRequest() rejects token lists where the same challenge PHID appears more than once: after exploding each element into phid/token it checks isset($token_map[$phid]) and throws, interpolating the duplicated PHID into the message. One challenge may only be answered once per request.","triggerScenarios":"A request submits two mfa elements for the same challenge, e.g. mfa[]=PHID-CHAL-aaa:tok1 together with mfa[]=PHID-CHAL-aaa:tok2 - duplicated hidden inputs, a buggy double-submit that merges two forms, or crafted parameters.","commonSituations":"Client JS appending a second response for an already-answered challenge; form duplication from back/forward navigation; scripts replaying a response token plus a replacement token for the same challenge.","solutions":["Submit each challenge token exactly once per request - remove duplicate mfa inputs","Reload the MFA prompt from the normal UI to get a clean form with one input per challenge","If you build the client, deduplicate elements by PHID before sending (keep the newest)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Deduplicate mfa elements by challenge PHID before submitting:\n$map = array();\nforeach ($submitted_mfa as $element) {\n  $element = trim($element, ' ,');\n  if (!strlen($element)) { continue; }\n  list($phid, ) = explode(':', $element, 2);\n  $map[$phid] = $element; // one response per challenge, last one wins\n}\n$submitted_mfa = array_values($map);","typeGuard":null,"tryCatchPattern":"try {\n  $responses = PhabricatorAuthChallenge::newChallengeResponsesFromRequest(\n    $challenges, $request);\n} catch (Exception $ex) {\n  // Duplicate or malformed challenge tokens: 400 and restart flow.\n  return new Aphront400Response();\n}","preventionTips":["Ensure the form renders exactly one hidden input per challenge - never append extra ones","On back/forward navigation, reload the MFA prompt instead of merging old and new inputs"],"tags":["mfa","phabricator","request-validation","duplicate-parameter"],"backgroundTag":"mfa-challenge-token-invalid","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}