phacility/phabricator · error · Exception
This request improperly specifies an MFA challenge token ("%
Error message
This request improperly specifies an MFA challenge token ("%s") multiple times and can not be processed. What it means
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.
Source
Thrown at src/applications/auth/storage/PhabricatorAuthChallenge.php:86
if (!strlen($token_element)) {
continue;
}
// NOTE: This error message is intentionally not printing the token to
// avoid disclosing it. As a result, it isn't terribly useful, but no
// normal user should ever end up here.
if (!preg_match('/^[^:]+:/', $token_element)) {
throw new Exception(
pht(
'This request included an improperly formatted MFA challenge '.
'token and can not be processed.'));
}
list($phid, $token) = explode(':', $token_element, 2);
if (isset($token_map[$phid])) {
throw new Exception(
pht(
'This request improperly specifies an MFA challenge token ("%s") '.
'multiple times and can not be processed.',
$phid));
}
$token_map[$phid] = new PhutilOpaqueEnvelope($token);
}
$challenges = mpull($challenges, null, 'getPHID');
$now = PhabricatorTime::getNow();
foreach ($challenges as $challenge_phid => $challenge) {
// If the response window has expired, don't attach the token.
if ($challenge->getResponseTTL() < $now) {
continue;
}
View on GitHub (pinned to 5720a38cfe)
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)
Defensive patterns
Strategy: validation
Validate before calling
// Deduplicate mfa elements by challenge PHID before submitting:
$map = array();
foreach ($submitted_mfa as $element) {
$element = trim($element, ' ,');
if (!strlen($element)) { continue; }
list($phid, ) = explode(':', $element, 2);
$map[$phid] = $element; // one response per challenge, last one wins
}
$submitted_mfa = array_values($map); Try / catch
try {
$responses = PhabricatorAuthChallenge::newChallengeResponsesFromRequest(
$challenges, $request);
} catch (Exception $ex) {
// Duplicate or malformed challenge tokens: 400 and restart flow.
return new Aphront400Response();
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- This request included an improperly formatted MFA challenge
- Your account has too many outstanding, incomplete MFA synchr
- This Duo enrollment attempt is invalid or has expired ("%s")
- Invalid response token for this challenge: token digest does
- The "Has MFA" query constraint may only be used by administr
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/a3d0e9b5b4395f4d.
Report an issue: GitHub.