immich-app/immich · error · Error

Invalid SMTP configuration

Error message

Invalid SMTP configuration

What it means

On the ConfigValidate event, NotificationService verifies the SMTP transport whenever notifications.smtp is enabled and has changed. If verifySmtp throws, the catch logs the error and rethrows a plain Error 'Invalid SMTP configuration' with the cause. Because this fires during config save validation, a failure blocks the new system config from being persisted.

Source

Thrown at server/src/services/notification.service.ts:137

    this.websocketRepository.clientBroadcast('AppRestartV1', {
      isMaintenanceMode: state.isMaintenanceMode,
    });

    this.websocketRepository.serverSend('AppRestart', state);
  }

  @OnEvent({ name: 'ConfigValidate', priority: -100 })
  async onConfigValidate({ oldConfig, newConfig }: ArgOf<'ConfigValidate'>) {
    try {
      if (
        newConfig.notifications.smtp.enabled &&
        !isEqualObject(oldConfig.notifications.smtp, newConfig.notifications.smtp)
      ) {
        await this.emailRepository.verifySmtp(newConfig.notifications.smtp.transport);
      }
    } catch (error: Error | any) {
      this.logger.error(`Failed to validate SMTP configuration: ${error}`, error?.stack);
      throw new Error('Invalid SMTP configuration', { cause: error });
    }
  }

  @OnEvent({ name: 'AssetHide' })
  onAssetHide({ assetId, userId }: ArgOf<'AssetHide'>) {
    this.websocketRepository.clientSend('on_asset_hidden', userId, assetId);
  }

  @OnEvent({ name: 'AssetShow' })
  async onAssetShow({ assetId }: ArgOf<'AssetShow'>) {
    await this.jobRepository.queue({ name: JobName.AssetGenerateThumbnails, data: { id: assetId, notify: true } });
  }

  @OnEvent({ name: 'AssetTrash' })
  onAssetTrash({ assetId, userId }: ArgOf<'AssetTrash'>) {
    this.websocketRepository.clientSend('on_asset_trash', userId, [assetId]);
  }

View on GitHub (pinned to 199723261c)

Solutions

  1. Read error.cause and the 'Failed to validate SMTP configuration' log for the underlying SMTP error.
  2. Correct host, port, username, password, and security (SSL vs STARTTLS) in the SMTP config payload.
  3. Use the admin test-email flow first to verify credentials before saving system config.
  4. Ensure network/firewall allows the Immich server outbound to the SMTP host:port.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify SMTP before saving system config
import nodemailer from 'nodemailer';
const transporter = nodemailer.createTransport(newConfig.notifications.smtp.transport);
await transporter.verify(); // throws on bad config
await api.systemConfigApi.updateConfig(newConfig);

Try / catch

try {
  await api.systemConfigApi.updateConfig(newConfig);
} catch (e) {
  if (/Invalid SMTP configuration/.test(String(e?.message))) {
    // read e.cause - correct host/port/credentials/security before retry
  } else throw e;
}

Prevention

When it happens

Trigger: Admin PATCHes /system-config with notifications.smtp.enabled=true and a changed transport that fails verification (unreachable host, bad credentials, TLS problem). The ConfigValidate handler runs and throws before the save completes.

Common situations: Enabling SMTP notifications for the first time with unverified settings; changing SMTP host/port/password; switching security modes incorrectly; SMTP provider outage during save.

Related errors


AI-assisted analysis of immich-app/immich@199723261c (2026-08-12). Data as JSON: /api/errors/2c8c062506606a65. Report an issue: GitHub.