phacility/phabricator · error · Exception

Hasher "%s" may produce hashes which are too long to fit in

Error message

Hasher "%s" may produce hashes which are too long to fit in storage. %d characters are available, but its hashes may be up to %d characters in length.

What it means

Password hashes are stored as 'name:hash' strings in a fixed-size storage column, capped by PhabricatorPasswordHasher::MAXIMUM_STORAGE_SIZE (128 characters). When hasher classes are discovered (getAllHashers), each one is checked: strlen(getHashName()) + getHashLength() + 1 must fit within 128. A hasher that could exceed the cap is rejected at discovery time so a password can never be hashed into something un-storable.

Source

Thrown at src/infrastructure/util/password/PhabricatorPasswordHasher.php:227

   * actually be used (for example, a required extension is missing).
   *
   * @return list<PhabricatorPasswordHasher> Hasher objects.
   * @task hashing
   */
  public static function getAllHashers() {
    $objects = id(new PhutilClassMapQuery())
      ->setAncestorClass(__CLASS__)
      ->setUniqueMethod('getHashName')
      ->execute();

    foreach ($objects as $object) {
      $name = $object->getHashName();

      $potential_length = strlen($name) + $object->getHashLength() + 1;
      $maximum_length = self::MAXIMUM_STORAGE_SIZE;

      if ($potential_length > $maximum_length) {
        throw new Exception(
          pht(
            'Hasher "%s" may produce hashes which are too long to fit in '.
            'storage. %d characters are available, but its hashes may be '.
            'up to %d characters in length.',
            $name,
            $maximum_length,
            $potential_length));
      }
    }

    return $objects;
  }


  /**
   * Get all usable password hashers. This may include hashers which are
   * not desirable or advisable.
   *

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Shorten getHashName() to a compact unique identifier (e.g. 'xargon2') and keep parameters inside the hash body only if the total still fits.
  2. Reduce getHashLength() by encoding the digest more compactly (base64 instead of hex halves the length) so name + ':' + digest stays under 128.
  3. If the format genuinely cannot fit in 128 characters, the algorithm is not usable with Phabricator's storage schema — pick a shorter representation.
  4. Add a unit test asserting strlen($name) + $hasher->getHashLength() + 1 <= PhabricatorPasswordHasher::MAXIMUM_STORAGE_SIZE.

Example fix

// before
public function getHashName() {
  return 'argon2id-v=19-m=65536-t=4-p=1';   // 26 chars + long digest
}
public function getHashLength() {
  return 512;   // hex-encoded digest -> total exceeds 128
}

// after
public function getHashName() {
  return 'xargon2id';   // parameters live in the digest, not the name
}
public function getHashLength() {
  return 64;   // raw 32-byte digest, base64url-encoded
}
Defensive patterns

Strategy: validation

Validate before calling

// Check a custom hasher fits storage before registering it:
$name = $hasher->getHashName();
$length = strlen($name) + $hasher->getHashLength() + 1;
if ($length > PhabricatorPasswordHasher::MAXIMUM_STORAGE_SIZE) {
  throw new Exception(
    pht('Hasher %s needs %d chars but only %d are available.',
      $name, $length, PhabricatorPasswordHasher::MAXIMUM_STORAGE_SIZE));
}

Prevention

When it happens

Trigger: Registering a custom PhabricatorPasswordHasher subclass whose getHashName() plus getHashLength() totals more than 127 characters — e.g. a long algorithm identifier like 'super-argon2id-v19-m=65536,t=4,p=1' combined with a long raw or hex-encoded hash. The exception is thrown while enumerating hashers, which happens during password operations and authentication setup.

Common situations: Writing a custom hasher that returns the full algorithm parameters in getHashName(); returning getHashLength() as the base64/hex length of the encoded output when it should be the trimmed length; wrapping an external library that emits very long composite hashes.

Related errors


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