passbolt/passbolt_api · error · FormValidationException

Could not validate the smtp settings.

Error message

Could not validate the smtp settings.

What it means

Thrown by SmtpSettingsTestEmailService::validateAndGetSmtpSettings when the settings used to send a test email fail EmailConfigurationForm validation with the 'sendTestEmail' ruleset. Before passbolt attempts an SMTP connection it validates hostname, port, sender, credentials and TLS mode; invalid input raises FormValidationException so the client receives field-level errors rather than a cryptic SMTP transport failure.

Solutions

  1. Inspect the form errors returned in the API response (FormValidationException exposes getForm()->getErrors()) and correct the failing fields in the test request payload
  2. Ensure the payload includes all required SMTP fields: sender_name, sender_email, hostname, port, tls, username, password — matching what the settings page would submit
  3. If testing file-based settings, fix the values in config/passbolt.php (passbolt.email.transports / SMTP settings) so they pass validation, then retry the test email
  4. Use `passbolt send_test_email you@example.com` CLI to test connectivity with config-file settings, or re-save SMTP settings through the UI so validated data is stored before re-running the test

Example fix

// before
$service->sendTestEmail($admin, ['email' => 'admin@example.com', 'hostname' => '', 'port' => 'smtp']);
// after
$service->sendTestEmail($admin, [
    'email' => 'admin@example.com',
    'sender_name' => 'Passbolt',
    'sender_email' => 'no-reply@example.com',
    'hostname' => 'smtp.example.com',
    'port' => 587,
    'tls' => true,
    'username' => 'smtp-user',
    'password' => 'smtp-pass',
]);
Defensive patterns

Strategy: validation

Validate before calling

$form = new \Passbolt\SmtpSettings\Form\EmailConfigurationForm();
if (!$form->execute($data, ['validate' => 'sendTestEmail'])) {
    $errors = $form->getErrors(); // resolve before calling sendTestEmail
}

Type guard

function canSendTestEmail(array $data): bool
{
    return !empty($data['hostname'])
        && is_numeric($data['port'] ?? null)
        && filter_var($data['sender_email'] ?? '', FILTER_VALIDATE_EMAIL) !== false
        && filter_var($data['email'] ?? '', FILTER_VALIDATE_EMAIL) !== false;
}

Try / catch

try {
    $this->SmtpSettingsTestEmailService->sendTestEmail($admin, $data);
} catch (\App\Error\Exception\FormValidationException $e) {
    $fieldErrors = $e->getForm()->getErrors();
    // surface field errors to the admin UI instead of attempting SMTP
}

Prevention

When it happens

Trigger: POST /smtp/settings/test with a payload whose hostname is empty or malformed, port is non-numeric/out of range, sender_email is invalid, or missing username/password for an authenticated SMTP transport — e.g. testing before saving settings, or testing settings coming from a legacy/invalid config file.

Common situations: Admin enters the email address of the recipient but the form data sent still contains empty or stale SMTP host/port fields; testing file-based (config) settings that were hand-edited with a bad port or TLS value; migrating from file config to DB where old config lacks required fields the newer validation ruleset enforces; automation scripts calling the test endpoint with partial payloads.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsTestEmailService.php:157

        if (!empty($this->smtpSettings['client_secret'])) {
            $toReplace[] = $this->smtpSettings['client_secret'];
            $replaceWith[] = $replaceMask;
        }

        return str_replace($toReplace, $replaceWith, $str);
    }

    /**
     * @param array $data Data in the payload
     * @return array
     * @throws \App\Error\Exception\FormValidationException if the data passed do not validate the EmailConfigurationForm
     */
    public function validateAndGetSmtpSettings(array $data): array
    {
        $form = new EmailConfigurationForm();

        if (!$form->execute($data, ['validate' => 'sendTestEmail'])) {
            throw new FormValidationException(__('Could not validate the smtp settings.'), $form);
        }

        return (array)$form->getData();
    }
}

View on GitHub (pinned to 31c1bbc10f)