phacility/phabricator · error · PhabricatorSearchConstraintException
The "Has MFA" query constraint may only be used by administr
Error message
The "Has MFA" query constraint may only be used by administrators, to prevent attackers from using it to target weak accounts.
What it means
The People directory search engine throws PhabricatorSearchConstraintException when a non-administrator viewer applies the 'Has MFA' constraint (mfa on the query). The guard exists because filtering by MFA enrollment enumerates exactly which accounts lack MFA - a targeting primitive for attackers - so only administrators may use it. Saved-query parameters still carry the constraint, so a non-admin opening such a query triggers it immediately.
Source
Thrown at src/applications/people/query/PhabricatorPeopleSearchEngine.php:175
$query->withIsDisabled($map['isDisabled']);
}
if ($map['isMailingList'] !== null) {
$query->withIsMailingList($map['isMailingList']);
}
if ($map['isBot'] !== null) {
$query->withIsSystemAgent($map['isBot']);
}
if ($map['needsApproval'] !== null) {
$query->withIsApproved(!$map['needsApproval']);
}
if (idx($map, 'mfa') !== null) {
$viewer = $this->requireViewer();
if (!$viewer->getIsAdmin()) {
throw new PhabricatorSearchConstraintException(
pht(
'The "Has MFA" query constraint may only be used by '.
'administrators, to prevent attackers from using it to target '.
'weak accounts.'));
}
$query->withIsEnrolledInMultiFactor($map['mfa']);
}
if ($map['createdStart']) {
$query->withDateCreatedAfter($map['createdStart']);
}
if ($map['createdEnd']) {
$query->withDateCreatedBefore($map['createdEnd']);
}
return $query;View on GitHub (pinned to 5720a38cfe)
Solutions
- Run the query as an administrator - the constraint requires getIsAdmin() on the viewer
- Share results, not queries: export the list as admin instead of distributing the constrained query URL
- Remove the 'Has MFA' constraint from saved queries and dashboard panels intended for non-admin audiences
Example fix
// before: saved query visible to everyone carries mfa=0
// after: strip the constraint for shared queries, keep MFA reporting admin-only
if ($viewer->getIsAdmin()) {
$query->withIsEnrolledInMultiFactor($map['mfa']);
} Defensive patterns
Strategy: validation
Validate before calling
// Only apply the MFA constraint for administrators
if (idx($map, 'mfa') !== null) {
if (!$viewer->getIsAdmin()) {
unset($map['mfa']); // or reject the request explicitly
} else {
$query->withIsEnrolledInMultiFactor($map['mfa']);
}
} Type guard
function canUseMfaConstraint(PhabricatorUser $viewer) {
return (bool)$viewer->getIsAdmin();
} Prevention
- Gate any 'Has MFA' filter on viewer->getIsAdmin()
- Never share constrained query URLs or dashboards with non-admin audiences
- Export MFA-compliance lists as admin instead of distributing the query itself
When it happens
Trigger: A non-admin opens a People search URL or saved query containing `mfa=0` / `mfa=1`; a shared dashboard panel embeds an MFA-constrained user query viewed by regular users; a Conduit search built with the mfa field runs with a non-admin token.
Common situations: An admin shares a 'users without MFA' query link with a team; a dashboard panel with the constraint is visible org-wide; security-audit queries left in navigation that non-admins click.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Invalid response token for this challenge: token digest does
- This comment was signed with MFA, so edits to it must also b
- This transaction group requires MFA to apply, but you can no
- Unable to change ownership of an identity file to daemon use
- Failed to create directory "%s" for specified log file (with
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/660d23e42d0db0ec.
Report an issue: GitHub.