passbolt/passbolt_api · error · InternalErrorException

Unknown key validation rule

Error message

Unknown key validation rule: {0}

What it means

InternalErrorException thrown in the rule-switch of parseAndValidatePublicKey when a rule name is not among the known validation rules (falls into the default case). It guards against typos or stale rule names reaching the validation loop.

Solutions

  1. Fix the rule names in the custom rules array to match PublicKeyValidationService's supported rule constants.
  2. Omit the $rules parameter to use the built-in default rules.
  3. After upgrading passbolt, diff custom rules against the current supported rule list.
  4. Catch InternalErrorException and log the offending rule name from the message.

Example fix

// before
$rules = ['is_parsable_armored_key', 'has_valid_key_type']; // typo / unknown
PublicKeyValidationService::parseAndValidatePublicKey($key, $rules);

// after
$rules = ['is_parsable_armored_key', 'has_valid_key_type', 'is_not_revoked'];
$rules = array_intersect($rules, PublicKeyValidationService::getSupportedRules()); // drop unknown rules
PublicKeyValidationService::parseAndValidatePublicKey($key, $rules ?: null);
Defensive patterns

Strategy: validation

Validate before calling

// PHP
$supported = PublicKeyValidationService::getDefaultRules(); // reference set
$unknown = array_diff($rules, array_keys(array_flip($supported)));
if ($unknown) {
    throw new BadConfigurationException('Unknown rules: ' . implode(',', $unknown));
}

Type guard

function allRulesKnown(array $rules, array $knownRules): bool {
    return empty(array_diff($rules, $knownRules));
}

Try / catch

try {
    PublicKeyValidationService::parseAndValidatePublicKey($armoredKey, $customRules);
} catch (\Cake\Http\Exception\InternalErrorException $e) {
    Log::error($e->getMessage()); // logs 'Unknown key validation rule: X'
    throw new BadConfigurationException('Fix unknown key validation rules in config.');
}

Prevention

When it happens

Trigger: Calling parseAndValidatePublicKey with a custom $rules array containing a misspelled or removed rule name, e.g. ['is_parsable_armored_key', 'has_valide_key_size'] (typo), or a rule name from an older passbolt version.

Common situations: Custom config or overridden getDefaultRules() after a version upgrade renamed rules; dynamic rule assembly with string constants that drifted.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/6099ab32c8a4efd6. Report an issue: GitHub.

Appendix: source

Thrown at src/Service/OpenPGP/PublicKeyValidationService.php:235

                case self::IS_NOT_REVOKED_RULE:
                    if ($keyInfo['revoked']) {
                        $validationErrors[$ruleName] = __('The key must not be revoked.');
                    }
                    break;
                case self::HAS_NO_EXTRA_BREAK_LINE_RULE:
                    if (self::hasExtraBreakline($armoredKey)) {
                        $msg = __('The armored key must not contain an extra line before the end block.');
                        $validationErrors[$ruleName] = $msg;
                    }
                    break;
                case self::HAS_MULTIPLE_MAIN_PACKETS_RULE:
                    if ($keyInfo['public_key_packet_counts'] > 1 || $keyInfo['secret_key_packet_counts'] > 1) {
                        $msg = __('The armored key must not contain multiple keys.');
                        $validationErrors[$ruleName] = $msg;
                    }
                    break;
                default:
                    throw new InternalErrorException(__('Unknown key validation rule: {0}', $ruleName));
            }
        }

        // Wrap all errors together in a custom validation exception
        if (count($validationErrors)) {
            throw new CustomValidationException(__('The public key could not be validated.'), [
                'armored_key' => $validationErrors,
            ]);
        }

        // Or return key information for further use
        // for example for it to be saved in a model
        return $keyInfo;
    }

    /**
     * Return true if the date is in the future, false if in the past or not a valid date
     *

View on GitHub (pinned to 31c1bbc10f)