{"record":{"id":"65ff77cc2cb873ac","repo":"passbolt/passbolt_api","slug":"invalid-passbolt-plugins-smtpsettings-security-configuration","errorCode":null,"errorMessage":"Invalid `passbolt.plugins.smtpSettings.security` configuration values.","messagePattern":"Invalid `passbolt\\.plugins\\.smtpSettings\\.security` configuration values\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsSslOptionsGetService.php","lineNumber":83,"sourceCode":"        return $this->default;\n    }\n\n    /**\n     * @return array\n     * @thows BadRequestException Any configuration value set is not of valid type.\n     */\n    private function getConfigOptions(): array\n    {\n        $values = Configure::read('passbolt.plugins.smtpSettings.security', []);\n\n        $form = new CustomSslOptionsForm();\n        $valid = $form->validate($values);\n        if (!$valid) {\n            $errors = Hash::flatten($form->getErrors());\n            $errorMessage = __('Invalid `passbolt.plugins.smtpSettings.security` configuration values.');\n            $errorMessage .= ' ' . __('Errors: ') . implode('; ', $errors);\n\n            throw new BadRequestException($errorMessage);\n        }\n\n        return $values;\n    }\n\n    /**\n     * Checks if SSL options set in configuration are defaults.\n     *\n     * @param array $configOptions SSL options set in configuration.\n     * @return bool\n     */\n    private function checkDefaultOptions(array $configOptions): bool\n    {\n        if (count($configOptions) !== 4) {\n            $this->default = false;\n\n            return false;\n        }","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsSslOptionsGetService.php#L65-L101","documentation":"Thrown by SmtpSettingsSslOptionsGetService::getConfigOptions when the values configured under passbolt.plugins.smtpSettings.security fail CustomSslOptionsForm validation. These settings map to PHP stream SSL context options (sslVerifyPeer, sslVerifyPeerName, sslAllowSelfSigned, sslCafile); invalid types or values make the SMTP client's TLS options unusable, so a BadRequestException with the flattened per-field errors is raised instead of silently sending insecure SMTP traffic.","triggerScenarios":"Any call to SmtpSettingsSslOptionsGetService::get() or isDefault() (used when building SMTP transport options, e.g. sending a test email or reading settings) while config/passbolt.php or app.php contains `security` entries with wrong types or values — e.g. sslVerifyPeer set to string 'true' instead of boolean, a missing sslCafile file, or an unknown key combined with the wrong shape of data.","commonSituations":"Copy-pasting YAML/JSON config where booleans become strings ('false' vs false); pointing sslCafile to a non-existent CA bundle path; setting sslAllowSelfSigned without also providing sslCafile if the form requires it; typos like ssl_verify_peer instead of sslVerifyPeer in passbolt.plugins.smtpSettings.security.","solutions":["Read the flattened field errors appended to the exception message ('Errors: ...') to identify which key is invalid","Set each option with the correct PHP type: 'sslVerifyPeer' => true|false (bool), 'sslVerifyPeerName' => bool, 'sslAllowSelfSigned' => bool, 'sslCafile' => valid absolute path to a readable CA file","Remove the passbolt.plugins.smtpSettings.security block entirely to fall back to default secure TLS behavior if custom options are not needed","If providing sslAllowSelfSigned => true or custom CA, ensure sslCafile points to an existing PEM file (e.g. /etc/ssl/certs/ca-certificates.crt)","Clear the cached config (rm -rf tmp/cache/persistent*) after editing config files so the new values are picked up"],"exampleFix":"// before (config/passbolt.php)\n'security' => [\n    'sslVerifyPeer' => 'false',           // string, not bool\n    'sslAllowSelfSigned' => true,\n    // sslCafile missing\n],\n// after\n'security' => [\n    'sslVerifyPeer' => false,\n    'sslVerifyPeerName' => false,\n    'sslAllowSelfSigned' => true,\n    'sslCafile' => '/etc/ssl/certs/ca-certificates.crt',\n],","handlingStrategy":"validation","validationCode":"$values = Configure::read('passbolt.plugins.smtpSettings.security', []);\n$form = new \\Passbolt\\SmtpSettings\\Form\\CustomSslOptionsForm();\nif (!empty($values) && !$form->validate($values)) {\n    // fix before any SMTP send/read triggers the exception\n    debug(Hash::flatten($form->getErrors()));\n}","typeGuard":"function sslOptionsAreValidTypes(array $v): bool\n{\n    return (isset($v['sslVerifyPeer']) && !is_bool($v['sslVerifyPeer'])) === false\n        && (isset($v['sslVerifyPeerName']) && !is_bool($v['sslVerifyPeerName'])) === false\n        && (isset($v['sslAllowSelfSigned']) && !is_bool($v['sslAllowSelfSigned'])) === false\n        && (!isset($v['sslCafile']) || is_string($v['sslCafile']));\n}","tryCatchPattern":"try {\n    $sslOptions = $sslOptionsService->get();\n} catch (\\Cake\\Http\\Exception\\BadRequestException $e) {\n    $this->log('Invalid smtpSettings.security config: ' . $e->getMessage());\n    $sslOptions = []; // default secure TLS options\n}","preventionTips":["Always write booleans as true/false in PHP config, never quoted 'true'/'false' strings","Verify sslCafile path exists and is readable at deploy time (file_exists + is_readable check in provisioning)","Use the exact camelCase keys (sslVerifyPeer, sslVerifyPeerName, sslAllowSelfSigned, sslCafile)","Clear cached config after edits and re-run `passbolt send_test_email` to validate the TLS config early"],"tags":["config","validation","tls","ssl","smtp-settings"],"backgroundTag":"invalid-config-value","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}