{"record":{"id":"1f3d51fb31265301","repo":"phacility/phabricator","slug":"keyring-specifies-an-invalid-key-s-key-mater-1f3d51","errorCode":null,"errorMessage":"Keyring specifies an invalid key (\"%s\"): key material should be 32 bytes (256 bits) but has length %s.","messagePattern":"Keyring specifies an invalid key \\(\"(.+?)\"\\): key material should be 32 bytes \\(256 bits\\) but has length (.+?)\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/files/keyring/PhabricatorKeyringConfigOptionType.php","lineNumber":84,"sourceCode":"              pht(\n                'Keyring is configured with a \"%s\" key, but the PHP OpenSSL '.\n                'extension is not installed. Install the OpenSSL extension '.\n                'to enable encryption.',\n                $type));\n          }\n\n          $material = $spec['material.base64'];\n          $material = base64_decode($material, true);\n          if ($material === false) {\n            throw new Exception(\n              pht(\n                'Keyring specifies an invalid key (\"%s\"): key material '.\n                'should be base64 encoded.',\n                $name));\n          }\n\n          if (strlen($material) != 32) {\n            throw new Exception(\n              pht(\n                'Keyring specifies an invalid key (\"%s\"): key material '.\n                'should be 32 bytes (256 bits) but has length %s.',\n                $name,\n                new PhutilNumber(strlen($material))));\n          }\n          break;\n        default:\n          throw new Exception(\n            pht(\n              'Keyring configuration is invalid: it describes a key with '.\n              'type \"%s\", but this type is unknown.',\n              $type));\n      }\n    }\n\n    if (count($defaults) > 1) {\n      throw new Exception(","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/files/keyring/PhabricatorKeyringConfigOptionType.php#L66-L102","documentation":"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.","triggerScenarios":"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).","commonSituations":"Reusing a key generated for another cipher; typing a passphrase and base64-ing it; material passing through a pipeline that encodes twice.","solutions":["Regenerate the key as exactly 32 random bytes: php -r 'echo base64_encode(random_bytes(32)), PHP_EOL;'","Verify the decoded length: php -r 'echo strlen(base64_decode(\"<VALUE>\", true));' must print 32","If you intended a passphrase-derived key, that is not supported — use random key material"],"exampleFix":"# before: 16-byte key\n\"material.base64\": \"MTIzNDU2Nzg5MGFiY2RlZg==\"  # decodes to 16 bytes\n\n# after: 32-byte key\nphp -r 'echo base64_encode(random_bytes(32)), PHP_EOL;'  # paste result\n\"material.base64\": \"oPHAD/7m2Xy0Zl+Bq1c8Yk0PM4YfNpLrS4jEwVnN0F0=\"","handlingStrategy":"validation","validationCode":"$decoded = base64_decode($material, true);\nif ($decoded !== false && strlen($decoded) !== 32) {\n  // Key \"{$name}\" is \".strlen($decoded).\" bytes; AES-256 requires exactly 32.\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always generate 32 random bytes: php -r 'echo base64_encode(random_bytes(32));'","Verify length after any transformation pipeline: strlen(base64_decode($v, true)) === 32","Do not reuse keys cut for AES-128 or derived from passphrases"],"tags":["config","keyring","encryption","validation","phabricator"],"backgroundTag":"invalid-key-length","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}