immich-app/immich · error · BadRequestException
Failed to verify SMTP configuration
Error message
Failed to verify SMTP configuration
What it means
Before sending a test email, Immich calls emailRepository.verifySmtp(dto.transport) to confirm the SMTP server is reachable and credentials work. If that throws (connection refused, auth failure, TLS handshake error, timeout), the service wraps it into 400 BadRequestException 'Failed to verify SMTP configuration' with the original error as cause, so the admin gets actionable feedback without revealing internal details.
Source
Thrown at server/src/services/notification-admin.service.ts:34
level: dto.level ?? NotificationLevel.Info,
title: dto.title,
description: dto.description,
data: dto.data,
});
return mapNotification(item);
}
async sendTestEmail(id: string, dto: SystemConfigSmtpDto, tempTemplate?: string) {
const user = await this.userRepository.get(id, { withDeleted: false });
if (!user) {
throw new Error('User not found');
}
try {
await this.emailRepository.verifySmtp(dto.transport);
} catch (error) {
throw new BadRequestException('Failed to verify SMTP configuration', { cause: error });
}
const { server } = await this.getConfig({ withCache: false });
const { html, text } = await this.emailRepository.renderEmail({
template: EmailTemplate.TEST_EMAIL,
data: {
baseUrl: getExternalDomain(server),
displayName: user.name,
},
customTemplate: tempTemplate!,
});
const { messageId } = await this.emailRepository.sendEmail({
to: user.email,
subject: 'Test email from Immich',
html,
text,
from: dto.from,
replyTo: dto.replyTo || dto.from,View on GitHub (pinned to 199723261c)
Solutions
- Read error.cause for the SMTP-level message (auth error, ECONNREFUSED, etc.).
- Verify host, port, and security mode (SSL/465 vs STARTTLS/587) against your provider's docs.
- Use a valid app-specific password (e.g. Gmail/Gmail SMTP app password, not the account password).
- Confirm outbound SMTP is allowed from the Immich host/container (test with openssl s_client / swaks).
Defensive patterns
Strategy: try-catch
Validate before calling
// before sending, sanity-check SMTP connectivity
import net from 'net';
await new Promise<void>((resolve, reject) => {
const socket = net.createConnection({ host: smtp.host, port: smtp.port }, () => {
socket.end();
resolve();
});
socket.on('error', reject);
setTimeout(() => reject(new Error('SMTP connect timeout')), 5000);
}); Try / catch
try {
await adminApi.sendTestEmail(userId, smtpDto);
} catch (e) {
if (e.status === 400 && /Failed to verify SMTP/.test(e.message)) {
// inspect e.cause for auth/TLS/connection detail and correct config
} else throw e;
} Prevention
- Use the test-email flow to validate SMTP before enabling notifications.
- Keep app-specific passwords for providers like Gmail; never the account password.
- Confirm outbound SMTP port reachability from the Immich host.
When it happens
Trigger: POST admin test-email (or saving SMTP settings) where the configured SMTP transport cannot be reached or rejects the connection: wrong host/port, bad credentials, STARTTLS mismatch, firewall blocking outbound SMTP.
Common situations: Typo in SMTP host; port 465/587 blocked by provider/firewall; username or app-password wrong; SMTP server requires TLS but config has plain; reverse DNS / SPF issues causing rejection.
Related errors
- Invalid SMTP configuration
- Failed to verify SMTP configuration
- Real-time transcoding is not enabled
- User not found
- Notification not found
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/5d6cb3ddbc75574c.
Report an issue: GitHub.