phacility/phabricator · error · Exception

Keyring specifies an invalid key ("%s"): key material should

Error message

Keyring specifies an invalid key ("%s"): key material should be 32 bytes (256 bits) but has length %s.

What it means

After strict base64 decoding, key material for an aes-256-cbc key must be exactly 32 bytes (256 bits); the validator measures strlen() and reports the actual length when it differs. This guarantees the material matches the AES-256 key size the storage format passes to openssl_decrypt/encrypt.

Source

Thrown at src/applications/files/keyring/PhabricatorKeyringConfigOptionType.php:84

              pht(
                'Keyring is configured with a "%s" key, but the PHP OpenSSL '.
                'extension is not installed. Install the OpenSSL extension '.
                'to enable encryption.',
                $type));
          }

          $material = $spec['material.base64'];
          $material = base64_decode($material, true);
          if ($material === false) {
            throw new Exception(
              pht(
                'Keyring specifies an invalid key ("%s"): key material '.
                'should be base64 encoded.',
                $name));
          }

          if (strlen($material) != 32) {
            throw new Exception(
              pht(
                'Keyring specifies an invalid key ("%s"): key material '.
                'should be 32 bytes (256 bits) but has length %s.',
                $name,
                new PhutilNumber(strlen($material))));
          }
          break;
        default:
          throw new Exception(
            pht(
              'Keyring configuration is invalid: it describes a key with '.
              'type "%s", but this type is unknown.',
              $type));
      }
    }

    if (count($defaults) > 1) {
      throw new Exception(

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Regenerate the key as exactly 32 random bytes: php -r 'echo base64_encode(random_bytes(32)), PHP_EOL;'
  2. Verify the decoded length: php -r 'echo strlen(base64_decode("<VALUE>", true));' must print 32
  3. If you intended a passphrase-derived key, that is not supported — use random key material

Example fix

# before: 16-byte key
"material.base64": "MTIzNDU2Nzg5MGFiY2RlZg=="  # decodes to 16 bytes

# after: 32-byte key
php -r 'echo base64_encode(random_bytes(32)), PHP_EOL;'  # paste result
"material.base64": "oPHAD/7m2Xy0Zl+Bq1c8Yk0PM4YfNpLrS4jEwVnN0F0="
Defensive patterns

Strategy: validation

Validate before calling

$decoded = base64_decode($material, true);
if ($decoded !== false && strlen($decoded) !== 32) {
  // Key "{$name}" is ".strlen($decoded)." bytes; AES-256 requires exactly 32.
}

Prevention

When it happens

Trigger: Base64 of a 16-byte (AES-128) or 24-byte key; base64 of a human passphrase instead of 32 random bytes; double-base64-encoded material decoding to a non-32-byte intermediate; base64 of a hex string (64 characters).

Common situations: Reusing a key generated for another cipher; typing a passphrase and base64-ing it; material passing through a pipeline that encodes twice.

Related errors


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