passbolt/passbolt_api · error · InternalErrorException

Unknown key validation rule

Error message

Unknown key validation rule: {0}

What it means

parseAndValidateMessage iterates the configured rule list; when it encounters a rule name it does not recognize in its switch statement, it throws InternalErrorException 'Unknown key validation rule: {0}'. This indicates a programming/config error: someone supplied a rule name outside the supported set (IS_PARSABLE_ARMORED_MESSAGE_RULE, HAS_KEY_ID, HAS_EXACTLY_ONE_RECIPIENT, etc.).

Solutions

  1. Use the class constants (MessageValidationService::HAS_KEY_ID, ::HAS_EXACTLY_ONE_RECIPEIENT-style names as defined in MessageValidationService) instead of string literals.
  2. Grep your codebase for custom rule arrays and compare against the switch cases in MessageValidationService::parseAndValidateMessage.
  3. Update integration code after passbolt version upgrades if rule names changed.
  4. Default to getDefaultRules() when custom rules are not strictly needed.

Example fix

// before
$rules = ['has_key_id' => true];
// after
$rules = [MessageValidationService::HAS_KEY_ID];
Defensive patterns

Strategy: validation

Validate before calling

$known = [IS_PARSABLE_ARMORED_MESSAGE_RULE, HAS_KEY_ID, HAS_EXACTLY_ONE_RECIPIENT];
if (array_diff($rules, $known)) { throw new LogicException('unknown rule'); }

Try / catch

try { parseAndValidateMessage($msg, $rules); } catch (InternalErrorException $e) { /* fix rule names */ }

Prevention

When it happens

Trigger: Calling parseAndValidateMessage with a custom $rules array containing a typo or an unsupported rule key (e.g. 'has_recipient' instead of the class constants).

Common situations: Plugin/integration code constructing custom rule lists, refactors renaming rule constants, copy-pasted rule names from documentation of a different version.

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/e2572b248a7f6e39. Report an issue: GitHub.

Appendix: source

Thrown at src/Service/OpenPGP/MessageValidationService.php:130

                    }
                    break;
                case self::HAS_ASYMMETRIC_PACKET_RULE:
                    if (!$messageInfo['asymmetric']) {
                        $validationErrors[$ruleName] = __('The message must contain an asymmetric packet.');
                    }
                    break;
                case self::HAS_SYMMETRIC_PACKET_RULE:
                    if (!$messageInfo['symmetric']) {
                        $validationErrors[$ruleName] = __('The message must contain a symmetric packet.');
                    }
                    break;
                case self::HAS_EXACTLY_ONE_RECIPIENT:
                    if (count($messageInfo['recipients']) !== 1) {
                        $validationErrors[$ruleName] = __('The message must contain only one recipient.');
                    }
                    break;
                default:
                    throw new InternalErrorException(__('Unknown key validation rule: {0}', $ruleName));
            }
        }

        // Wrap all errors together in a custom validation exception
        if (count($validationErrors)) {
            $debug = 'The armored message could not be validated' . "\n";
            $debug .= $armoredMessage . "\n" . json_encode($validationErrors);
            Log::error($debug);
            throw new CustomValidationException(__('The armored message could not be validated.'), [
                'data' => $validationErrors,
            ]);
        }

        return $messageInfo;
    }

    /**
     * Get Message Info

View on GitHub (pinned to 31c1bbc10f)