phacility/phabricator · error · Exception

This request included an improperly formatted MFA challenge

Error message

This request included an improperly formatted MFA challenge token and can not be processed.

What it means

PhabricatorAuthChallenge::newChallengeResponsesFromRequest() parses the request's MFA challenge token list: each non-empty element must match '^[^:]+:' (a challenge PHID, colon, then the token). Elements that do not look like 'PHID:token' trigger this exception; the source comment notes the message deliberately does not echo the token to avoid disclosure, and that no normal user should ever reach it.

Source

Thrown at src/applications/auth/storage/PhabricatorAuthChallenge.php:77

    $token_list = $request->getStr(self::HTTPKEY);
    if ($token_list === null) {
      return;
    }
    $token_list = explode(' ', $token_list);

    $token_map = array();
    foreach ($token_list as $token_element) {
      $token_element = trim($token_element, ' ');

      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);
    }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Do not hand-craft MFA challenge parameters - replay exactly the values the rendered form generated
  2. Retry the operation from the normal UI so fresh, well-formed challenge inputs are produced
  3. If you control the client, debug what it actually submits for the mfa parameters and stop modifying them
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: never fabricate mfa parameters; only echo back what the
// server generated:
$params = PhabricatorAuthChallenge::newHTTPParametersFromChallenges($challenges);
// ...render $params as hidden inputs; on submit, re-validate shape:
foreach ($submitted_mfa as $element) {
  $element = trim($element, ' ,');
  if (strlen($element) && !preg_match('/^[^:]+:/', $element)) {
    unset($submitted_mfa[$element]); // drop malformed instead of fataling
  }
}

Try / catch

try {
  $responses = PhabricatorAuthChallenge::newChallengeResponsesFromRequest(
    $challenges, $request);
} catch (Exception $ex) {
  // Malformed client payload: answer 400, do not retry the same request.
  return new Aphront400Response();
}

Prevention

When it happens

Trigger: A request carries mfa challenge parameters not shaped like '<PHID>:<token>' - a hand-crafted or scripted request, a tampered form payload, or buggy client code that mangles the hidden MFA inputs the form generated via newHTTPParametersFromChallenges().

Common situations: Scripts or API clients poking MFA-protected endpoints with made-up parameters; browser extensions altering form fields; copy/paste corruption of hidden inputs.

Related errors


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