RocketChat/Rocket.Chat · error · MeteorError

error-email-send-failed

error-email-send-failed

Error message

Error trying to send email: ${errorMessage}

What it means

sendUserEmail wraps Mailer.send failures as error-email-send-failed (MeteorError, function 'RocketChat.saveUser'), embedding the transport's message in both the error text and the details. It fires while sending the welcome or password email during user creation/save, so a broken SMTP setup can abort the whole save.

Source

Thrown at apps/meteor/server/lib/users/saveUser/sendUserEmail.ts:42

	const email = {
		to: userData.email,
		from: settings.get<string>('From_Email'),
		subject,
		html,
		data: {
			email: userData.email,
			password: userData.password ?? '******',
			...(typeof userData.name !== 'undefined' ? { name: userData.name } : {}),
		},
	};

	try {
		await Mailer.send(email);
	} catch (error) {
		const errorMessage = typeof error === 'object' && error && 'message' in error ? error.message : '';

		throw new MeteorError('error-email-send-failed', `Error trying to send email: ${errorMessage}`, {
			function: 'RocketChat.saveUser',
			message: errorMessage,
		});
	}
}

export async function sendWelcomeEmail(userData: Pick<SaveUserData, 'email' | 'name' | 'password'>) {
	return sendUserEmail(settings.get('Accounts_UserAddedEmail_Subject'), html, userData);
}

export async function sendPasswordEmail(userData: Pick<SaveUserData, 'email' | 'name' | 'password'>) {
	return sendUserEmail(settings.get('Password_Changed_Email_Subject'), passwordChangedHtml, userData);
}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Verify SMTP settings under Administration > Settings > Email and use the 'send test email' action to reproduce
  2. Read the embedded errorMessage — 'self signed certificate' means enable trustTLS/ignoreTLS, 'Invalid login' means wrong credentials, 'getaddrinfo' means wrong host/DNS
  3. If email delivery must not block user creation, decouple it: catch or queue the email instead of letting it abort saveUser

Example fix

// before
await sendUserEmail(subject, html, userData); // SMTP down -> whole save fails

// after
try {
  await sendUserEmail(subject, html, userData);
} catch (e) {
  logger.error({ msg: 'welcome email failed', user: userData.email, reason: e.details?.message });
  // user creation proceeds; email is retried/queued by your own logic
}
Defensive patterns

Strategy: try-catch

Validate before calling

// smoke-test SMTP before enabling email-bearing user creation flows
// (Administration > Settings > Email > 'Send a test mail' exercises Mailer.send directly)

Type guard

const isEmailSendFailure = (e: unknown): e is { error: string; details?: { message?: string } } =>\n  typeof e === 'object' && e !== null && (e as { error?: unknown }).error === 'error-email-send-failed';

Try / catch

try {
  await sendUserEmail(subject, html, userData);
} catch (e) {
  if (isEmailSendFailure(e)) {
    logger.error({ msg: 'email send failed', reason: e.details?.message });
    queueForRetry(userData); // delivery failure must not abort user creation
  }
}

Prevention

When it happens

Trigger: Creating a user (saveUser with sendPassword/welcome email enabled) when SMTP settings are missing or wrong: no host configured, authentication rejected, TLS handshake failure, DNS resolution failure, or the provider rejecting the sender address.

Common situations: Fresh installs that never configured SMTP; credentials rotated or app passwords revoked (Gmail); From address not verified with the provider; firewall/DNS blocking outbound mail in containers.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/9855b78c67392d48. Report an issue: GitHub.