diff --git a/app/mailers/abuse_report_mailer.rb b/app/mailers/abuse_report_mailer.rb
index 1fa85064c57b2384470dabeaf775fe8967398003..1bf7deec5425ab6122390061bea0226087cf2103 100644
--- a/app/mailers/abuse_report_mailer.rb
+++ b/app/mailers/abuse_report_mailer.rb
@@ -10,7 +10,7 @@ def notify(abuse_report_id)
 
     @abuse_report = AbuseReport.find(abuse_report_id)
 
-    mail(
+    mail_with_locale(
       to: Gitlab::CurrentSettings.abuse_notification_email,
       subject: "#{@abuse_report.user.name} (#{@abuse_report.user.username}) was reported for abuse"
     )
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
index 94ed83a7d4a68ca7cd0af6ad1d62364c79376a19..bb8d20b8301ad40686801dd64ab94b2b749c5485 100644
--- a/app/mailers/application_mailer.rb
+++ b/app/mailers/application_mailer.rb
@@ -34,4 +34,23 @@ def default_reply_to_address
     address.display_name = Gitlab.config.gitlab.email_display_name
     address
   end
+
+  def mail_with_locale(headers = {}, &block)
+    locale = recipient_locale headers
+
+    Gitlab::I18n.with_locale(locale) do
+      mail(headers, &block)
+    end
+  end
+
+  def recipient_locale(headers = {})
+    to = Array(headers[:to])
+    locale = I18n.locale
+    locale = preferred_language_by_email(to.first) if to.one?
+    locale
+  end
+
+  def preferred_language_by_email(email)
+    User.find_by_any_email(email)&.preferred_language || I18n.locale
+  end
 end
diff --git a/app/mailers/email_rejection_mailer.rb b/app/mailers/email_rejection_mailer.rb
index 257216582856f0eb8dba0171eafb3d20affa7ba1..f681aa67a774d2bfaaf82f4419479afd020b267c 100644
--- a/app/mailers/email_rejection_mailer.rb
+++ b/app/mailers/email_rejection_mailer.rb
@@ -22,6 +22,6 @@ def rejection(reason, original_raw, can_retry = false)
 
     headers['Reply-To'] = @original_message.to.first if can_retry
 
-    mail(headers)
+    mail_with_locale(headers)
   end
 end
diff --git a/app/mailers/emails/admin_notification.rb b/app/mailers/emails/admin_notification.rb
index 3766b4447d1d106c83cfa41158c449dfd8c0c7bc..5c5497d8eb55601e01ff8d9760ca09b5e1aad2a7 100644
--- a/app/mailers/emails/admin_notification.rb
+++ b/app/mailers/emails/admin_notification.rb
@@ -7,13 +7,13 @@ def send_admin_notification(user_id, subject, body)
       email = user.notification_email_or_default
       @unsubscribe_url = unsubscribe_url(email: Base64.urlsafe_encode64(email))
       @body = body
-      mail to: email, subject: subject
+      mail_with_locale to: email, subject: subject
     end
 
     def send_unsubscribed_notification(user_id)
       user = User.find(user_id)
       email = user.notification_email_or_default
-      mail to: email, subject: "Unsubscribed from GitLab administrator notifications"
+      mail_with_locale to: email, subject: "Unsubscribed from GitLab administrator notifications"
     end
   end
 end
diff --git a/app/mailers/emails/groups.rb b/app/mailers/emails/groups.rb
index 07812a01202cb7e11800adda2c7c10fe377930a8..3c9bf41c2080c433a5d7fba11b3de1a3cc34a9bc 100644
--- a/app/mailers/emails/groups.rb
+++ b/app/mailers/emails/groups.rb
@@ -13,7 +13,7 @@ def group_was_not_exported_email(current_user, group, errors)
     def group_email(current_user, group, subj, errors: nil)
       @group = group
       @errors = errors
-      mail(to: current_user.notification_email_for(@group), subject: subject(subj))
+      mail_with_locale(to: current_user.notification_email_for(@group), subject: subject(subj))
     end
   end
 end
diff --git a/app/mailers/emails/in_product_marketing.rb b/app/mailers/emails/in_product_marketing.rb
index 1b46d4841b0c0f4df4ac107351c745d903b33ac4..972c1da065a30ed2d24184cdfbf9b653d2322668 100644
--- a/app/mailers/emails/in_product_marketing.rb
+++ b/app/mailers/emails/in_product_marketing.rb
@@ -31,7 +31,7 @@ def build_ios_app_guide_email(recipient_email)
 
     def mail_to(to:, subject:)
       custom_headers = Gitlab.com? ? CUSTOM_HEADERS : {}
-      mail(to: to, subject: subject, **custom_headers) do |format|
+      mail_with_locale(to: to, subject: subject, **custom_headers) do |format|
         format.html do
           @message.format = :html
 
diff --git a/app/mailers/emails/members.rb b/app/mailers/emails/members.rb
index c885e41671c2779e329499aa5edcddb6b287ed5d..33c955f94eeca92bb8a365368b5262b70b4c11ae 100644
--- a/app/mailers/emails/members.rb
+++ b/app/mailers/emails/members.rb
@@ -61,7 +61,7 @@ def member_invited_email(member_source_type, member_id, token)
 
       Gitlab::Tracking.event(self.class.name, 'invite_email_sent', label: 'invite_email', property: member_id.to_s)
 
-      mail(to: member.invite_email, subject: invite_email_subject, **invite_email_headers) do |format|
+      mail_with_locale(to: member.invite_email, subject: invite_email_subject, **invite_email_headers) do |format|
         format.html { render layout: 'unknown_user_mailer' }
         format.text { render layout: 'unknown_user_mailer' }
       end
diff --git a/app/mailers/emails/pages_domains.rb b/app/mailers/emails/pages_domains.rb
index 6c3dcf8746bbdbf9fad829631b3f0a8c0db36263..a6e9da18689378765491af56ec3be98938d2be7c 100644
--- a/app/mailers/emails/pages_domains.rb
+++ b/app/mailers/emails/pages_domains.rb
@@ -6,7 +6,7 @@ def pages_domain_enabled_email(domain, recipient)
       @domain = domain
       @project = domain.project
 
-      mail(
+      mail_with_locale(
         to: recipient.notification_email_for(@project.group),
         subject: subject("GitLab Pages domain '#{domain.domain}' has been enabled")
       )
@@ -16,7 +16,7 @@ def pages_domain_disabled_email(domain, recipient)
       @domain = domain
       @project = domain.project
 
-      mail(
+      mail_with_locale(
         to: recipient.notification_email_for(@project.group),
         subject: subject("GitLab Pages domain '#{domain.domain}' has been disabled")
       )
@@ -26,7 +26,7 @@ def pages_domain_verification_succeeded_email(domain, recipient)
       @domain = domain
       @project = domain.project
 
-      mail(
+      mail_with_locale(
         to: recipient.notification_email_for(@project.group),
         subject: subject("Verification succeeded for GitLab Pages domain '#{domain.domain}'")
       )
@@ -36,7 +36,7 @@ def pages_domain_verification_failed_email(domain, recipient)
       @domain = domain
       @project = domain.project
 
-      mail(
+      mail_with_locale(
         to: recipient.notification_email_for(@project.group),
         subject: subject("ACTION REQUIRED: Verification failed for GitLab Pages domain '#{domain.domain}'")
       )
@@ -47,7 +47,7 @@ def pages_domain_auto_ssl_failed_email(domain, recipient)
       @project = domain.project
 
       subject_text = _("ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'") % { domain: domain.domain }
-      mail(
+      mail_with_locale(
         to: recipient.notification_email_for(@project.group),
         subject: subject(subject_text)
       )
diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb
index 81f082b9680fa3a6c57323d9340c51fa813e3af2..8fe471a48f2a7008aedf6556177642692c0cb5cb 100644
--- a/app/mailers/emails/profile.rb
+++ b/app/mailers/emails/profile.rb
@@ -6,7 +6,7 @@ def new_user_email(user_id, token = nil)
       @current_user = @user = User.find(user_id)
       @target_url = user_url(@user)
       @token = token
-      mail(to: @user.notification_email_or_default, subject: subject("Account was created for you"))
+      mail_with_locale(to: @user.notification_email_or_default, subject: subject("Account was created for you"))
     end
 
     def instance_access_request_email(user, recipient)
@@ -42,7 +42,7 @@ def new_ssh_key_email(key_id)
 
       @current_user = @user = @key.user
       @target_url = user_url(@user)
-      mail(to: @user.notification_email_or_default, subject: subject("SSH key was added to your account"))
+      mail_with_locale(to: @user.notification_email_or_default, subject: subject("SSH key was added to your account"))
     end
     # rubocop: enable CodeReuse/ActiveRecord
 
@@ -54,7 +54,7 @@ def new_gpg_key_email(gpg_key_id)
 
       @current_user = @user = @gpg_key.user
       @target_url = user_url(@user)
-      mail(to: @user.notification_email_or_default, subject: subject("GPG key was added to your account"))
+      mail_with_locale(to: @user.notification_email_or_default, subject: subject("GPG key was added to your account"))
     end
     # rubocop: enable CodeReuse/ActiveRecord
 
@@ -66,7 +66,7 @@ def access_token_created_email(user, token_name)
       @token_name = token_name
 
       Gitlab::I18n.with_locale(@user.preferred_language) do
-        mail(to: @user.notification_email_or_default, subject: subject(_("A new personal access token has been created")))
+        mail_with_locale(to: @user.notification_email_or_default, subject: subject(_("A new personal access token has been created")))
       end
     end
 
@@ -79,7 +79,7 @@ def access_token_about_to_expire_email(user, token_names)
       @days_to_expire = PersonalAccessToken::DAYS_TO_EXPIRE
 
       Gitlab::I18n.with_locale(@user.preferred_language) do
-        mail(to: @user.notification_email_or_default, subject: subject(_("Your personal access tokens will expire in %{days_to_expire} days or less") % { days_to_expire: @days_to_expire }))
+        mail_with_locale(to: @user.notification_email_or_default, subject: subject(_("Your personal access tokens will expire in %{days_to_expire} days or less") % { days_to_expire: @days_to_expire }))
       end
     end
 
@@ -90,7 +90,7 @@ def access_token_expired_email(user)
       @target_url = profile_personal_access_tokens_url
 
       Gitlab::I18n.with_locale(@user.preferred_language) do
-        mail(to: @user.notification_email_or_default, subject: subject(_("Your personal access token has expired")))
+        mail_with_locale(to: @user.notification_email_or_default, subject: subject(_("Your personal access token has expired")))
       end
     end
 
@@ -102,7 +102,7 @@ def ssh_key_expired_email(user, fingerprints)
       @target_url = profile_keys_url
 
       Gitlab::I18n.with_locale(@user.preferred_language) do
-        mail(to: @user.notification_email_or_default, subject: subject(_("Your SSH key has expired")))
+        mail_with_locale(to: @user.notification_email_or_default, subject: subject(_("Your SSH key has expired")))
       end
     end
 
@@ -114,7 +114,7 @@ def ssh_key_expiring_soon_email(user, fingerprints)
       @target_url = profile_keys_url
 
       Gitlab::I18n.with_locale(@user.preferred_language) do
-        mail(to: @user.notification_email_or_default, subject: subject(_("Your SSH key is expiring soon.")))
+        mail_with_locale(to: @user.notification_email_or_default, subject: subject(_("Your SSH key is expiring soon.")))
       end
     end
 
@@ -137,7 +137,7 @@ def disabled_two_factor_email(user)
       @user = user
 
       Gitlab::I18n.with_locale(@user.preferred_language) do
-        mail(to: @user.notification_email_or_default, subject: subject(_("Two-factor authentication disabled")))
+        mail_with_locale(to: @user.notification_email_or_default, subject: subject(_("Two-factor authentication disabled")))
       end
     end
 
@@ -148,7 +148,7 @@ def new_email_address_added_email(user, email)
       @email = email
 
       Gitlab::I18n.with_locale(@user.preferred_language) do
-        mail(to: @user.notification_email_or_default, subject: subject(_("New email address added")))
+        mail_with_locale(to: @user.notification_email_or_default, subject: subject(_("New email address added")))
       end
     end
   end
diff --git a/app/mailers/emails/projects.rb b/app/mailers/emails/projects.rb
index 5b8471abb0fc86517137ef3ae1fc8409b4905a01..4bb624c27e927d44223b3cad3bcfc04975f8d42d 100644
--- a/app/mailers/emails/projects.rb
+++ b/app/mailers/emails/projects.rb
@@ -7,28 +7,29 @@ def project_was_moved_email(project_id, user_id, old_path_with_namespace)
       @project = Project.find project_id
       @target_url = project_url(@project)
       @old_path_with_namespace = old_path_with_namespace
-      mail(to: @user.notification_email_for(@project.group),
-           subject: subject("Project was moved"))
+      mail_with_locale(to: @user.notification_email_for(@project.group),
+                       subject: subject("Project was moved"))
     end
 
     def project_was_exported_email(current_user, project)
       @project = project
-      mail(to: current_user.notification_email_for(project.group),
-           subject: subject("Project was exported"))
+      mail_with_locale(to: current_user.notification_email_for(project.group),
+                       subject: subject("Project was exported"))
     end
 
     def project_was_not_exported_email(current_user, project, errors)
       @project = project
       @errors = errors
-      mail(to: current_user.notification_email_for(@project.group),
-           subject: subject("Project export error"))
+      mail_with_locale(to: current_user.notification_email_for(@project.group),
+                       subject: subject("Project export error"))
     end
 
     def repository_cleanup_success_email(project, user)
       @project = project
       @user = user
 
-      mail(to: user.notification_email_for(project.group), subject: subject("Project cleanup has completed"))
+      mail_with_locale(to: user.notification_email_for(project.group),
+                       subject: subject("Project cleanup has completed"))
     end
 
     def repository_cleanup_failure_email(project, user, error)
@@ -36,7 +37,7 @@ def repository_cleanup_failure_email(project, user, error)
       @user = user
       @error = error
 
-      mail(to: user.notification_email_for(project.group), subject: subject("Project cleanup failure"))
+      mail_with_locale(to: user.notification_email_for(project.group), subject: subject("Project cleanup failure"))
     end
 
     def repository_push_email(project_id, opts = {})
@@ -51,9 +52,9 @@ def repository_push_email(project_id, opts = {})
       add_project_headers
       headers['X-GitLab-Author'] = @message.author_username
 
-      mail(from: sender(@message.author_id, send_from_user_email: @message.send_from_committer_email?),
-           reply_to: @message.reply_to,
-           subject: @message.subject)
+      mail_with_locale(from: sender(@message.author_id, send_from_user_email: @message.send_from_committer_email?),
+                       reply_to: @message.reply_to,
+                       subject: @message.subject)
     end
 
     def prometheus_alert_fired_email(project, user, alert)
@@ -65,7 +66,7 @@ def prometheus_alert_fired_email(project, user, alert)
       add_alert_headers
 
       subject_text = "Alert: #{@alert.email_title}"
-      mail(to: user.notification_email_for(@project.group), subject: subject(subject_text))
+      mail_with_locale(to: user.notification_email_for(@project.group), subject: subject(subject_text))
     end
 
     def inactive_project_deletion_warning_email(project, user, deletion_date)
diff --git a/app/mailers/emails/releases.rb b/app/mailers/emails/releases.rb
index 4875abafe8d24580d87482a886d9c88898f69b8b..8fe93f59662c5840031395c591603fd0fc2a7b99 100644
--- a/app/mailers/emails/releases.rb
+++ b/app/mailers/emails/releases.rb
@@ -11,7 +11,7 @@ def new_release_email(user_id, release, reason = nil)
       )
       @recipient = User.find(user_id)
 
-      mail(
+      mail_with_locale(
         to: @recipient.notification_email_for(@project.group),
         subject: subject(release_email_subject)
       )
diff --git a/app/mailers/emails/remote_mirrors.rb b/app/mailers/emails/remote_mirrors.rb
index 9cde53918b9e3b25a8b82beb74ae4fee1f16cc5d..791ab7103b43a4c099fe302591142eafcf806741 100644
--- a/app/mailers/emails/remote_mirrors.rb
+++ b/app/mailers/emails/remote_mirrors.rb
@@ -7,7 +7,7 @@ def remote_mirror_update_failed_email(remote_mirror_id, recipient_id)
       @project = @remote_mirror.project
       user = User.find(recipient_id)
 
-      mail(to: user.notification_email_for(@project.group), subject: subject('Remote mirror update failed'))
+      mail_with_locale(to: user.notification_email_for(@project.group), subject: subject('Remote mirror update failed'))
     end
   end
 end
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index ed7681e595fd2f6921e33677e0699206271524a3..5a3fc70832c128bc0e3701497eb8d27d3f3de432 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -38,11 +38,11 @@ class Notify < ApplicationMailer
   helper InProductMarketingHelper
 
   def test_email(recipient_email, subject, body)
-    mail(to: recipient_email,
-         subject: subject,
-         body: body.html_safe,
-         content_type: 'text/html'
-        )
+    mail_with_locale(to: recipient_email,
+                     subject: subject,
+                     body: body.html_safe,
+                     content_type: 'text/html'
+                    )
   end
 
   # Splits "gitlab.corp.company.com" up into "gitlab.corp.company.com",
@@ -139,7 +139,7 @@ def mail_thread(model, headers = {})
       @reply_by_email = true
     end
 
-    mail(headers)
+    mail_with_locale(headers)
   end
 
   # `model` is used on EE code
@@ -225,7 +225,7 @@ def add_unsubscription_headers_and_links
   end
 
   def email_with_layout(to:, subject:, layout: 'mailer')
-    mail(to: to, subject: subject) do |format|
+    mail_with_locale(to: to, subject: subject) do |format|
       format.html { render layout: layout }
       format.text { render layout: layout }
     end
diff --git a/app/mailers/repository_check_mailer.rb b/app/mailers/repository_check_mailer.rb
index b8f990f26c87c314da1cd204f746c6853036823c..17c36c19955e17a6749f1746e926fe090eb4b1d9 100644
--- a/app/mailers/repository_check_mailer.rb
+++ b/app/mailers/repository_check_mailer.rb
@@ -14,7 +14,7 @@ def notify(failed_count)
         "#{failed_count} projects failed their last repository check"
       end
 
-    mail(
+    mail_with_locale(
       to: User.admins.active.pluck(:email),
       subject: "GitLab Admin | #{@message}"
     )
diff --git a/ee/app/mailers/ci_minutes_usage_mailer.rb b/ee/app/mailers/ci_minutes_usage_mailer.rb
index 6e4c27d8460a345de7afc3eaf3c66cb8c6595182..dd8642a12469731dc351640671eb4648e3585b77 100644
--- a/ee/app/mailers/ci_minutes_usage_mailer.rb
+++ b/ee/app/mailers/ci_minutes_usage_mailer.rb
@@ -8,7 +8,7 @@ class CiMinutesUsageMailer < ApplicationMailer
   def notify(namespace, recipients)
     @namespace = namespace
 
-    mail(
+    mail_with_locale(
       bcc: recipients,
       subject: "Action required: There are no remaining Pipeline minutes for #{@namespace.name}"
     )
@@ -18,7 +18,7 @@ def notify_limit(namespace, recipients, percentage_of_available_mins)
     @namespace = namespace
     @percentage_of_available_mins = percentage_of_available_mins
 
-    mail(
+    mail_with_locale(
       bcc: recipients,
       subject: "Action required: Less than #{percentage_of_available_mins}% " \
                "of Pipeline minutes remain for #{@namespace.name}"
diff --git a/ee/app/mailers/credentials_inventory_mailer.rb b/ee/app/mailers/credentials_inventory_mailer.rb
index 3a1414a64d3952ed5ae3fca78142e50f7358fbe9..b47261d6cced6aa31e9114fcce4c86353151838f 100644
--- a/ee/app/mailers/credentials_inventory_mailer.rb
+++ b/ee/app/mailers/credentials_inventory_mailer.rb
@@ -9,7 +9,7 @@ def personal_access_token_revoked_email(token:, revoked_by:)
     @revoked_by = revoked_by
     @token = token
 
-    mail(
+    mail_with_locale(
       to: token.user.notification_email_or_default,
       subject: _('Your Personal Access Token was revoked')
     )
@@ -19,7 +19,7 @@ def ssh_key_deleted_email(params:, deleted_by:)
     @deleted_by = deleted_by
     @params = params
 
-    mail(
+    mail_with_locale(
       to: params[:notification_email],
       subject: _('Your SSH key was deleted')
     )
diff --git a/ee/app/mailers/ee/emails/projects.rb b/ee/app/mailers/ee/emails/projects.rb
index 3a27827fc45731c9e61f30b0f4d49bfd5b009eaf..f14084f3997776cbfd48e34b7b6f3e212dec30a1 100644
--- a/ee/app/mailers/ee/emails/projects.rb
+++ b/ee/app/mailers/ee/emails/projects.rb
@@ -7,8 +7,8 @@ def mirror_was_hard_failed_email(project_id, user_id)
         @project = ::Project.find(project_id)
         user = ::User.find(user_id)
 
-        mail(to: user.notification_email_for(@project.group),
-             subject: subject('Repository mirroring paused'))
+        mail_with_locale(to: user.notification_email_for(@project.group),
+                         subject: subject('Repository mirroring paused'))
       end
 
       def mirror_was_disabled_email(project_id, user_id, deleted_user_name)
@@ -18,8 +18,8 @@ def mirror_was_disabled_email(project_id, user_id, deleted_user_name)
 
         return unless user
 
-        mail(to: user.notification_email_for(@project.group),
-             subject: subject('Repository mirroring disabled'))
+        mail_with_locale(to: user.notification_email_for(@project.group),
+                         subject: subject('Repository mirroring disabled'))
       end
 
       def project_mirror_user_changed_email(new_mirror_user_id, deleted_user_name, project_id)
@@ -27,8 +27,8 @@ def project_mirror_user_changed_email(new_mirror_user_id, deleted_user_name, pro
         @deleted_user_name = deleted_user_name
         user = ::User.find(new_mirror_user_id)
 
-        mail(to: user.notification_email_for(@project.group),
-             subject: subject('Mirror user changed'))
+        mail_with_locale(to: user.notification_email_for(@project.group),
+                         subject: subject('Mirror user changed'))
       end
 
       def user_escalation_rule_deleted_email(user, project, rules, recipient)
@@ -51,7 +51,7 @@ def incident_escalation_fired_email(project, user, issue)
         add_incident_headers
 
         subject_text = "Incident: #{@incident.title}"
-        mail(to: user.notification_email_for(@project.group), subject: subject(subject_text))
+        mail_with_locale(to: user.notification_email_for(@project.group), subject: subject(subject_text))
       end
     end
   end
diff --git a/ee/app/mailers/emails/namespace_storage_usage_mailer.rb b/ee/app/mailers/emails/namespace_storage_usage_mailer.rb
index eee9e44230c12edc9fa8845958233589c2461f44..cc44ad3636223e8cb9417c2374d65ea5a3f103c8 100644
--- a/ee/app/mailers/emails/namespace_storage_usage_mailer.rb
+++ b/ee/app/mailers/emails/namespace_storage_usage_mailer.rb
@@ -14,7 +14,7 @@ def notify_out_of_storage(namespace, recipients)
       @usage_quotas_url = usage_quotas_url(namespace, anchor: 'storage-quota-tab')
       @buy_storage_url = buy_storage_url(namespace)
 
-      mail(
+      mail_with_locale(
         bcc: recipients,
         subject: s_("NamespaceStorage|Action required: Storage has been exceeded for %{namespace_name}" % { namespace_name: namespace.name })
       )
@@ -27,7 +27,7 @@ def notify_limit_warning(namespace, recipients, percentage_of_available_storage,
       @percentage_of_available_storage = percentage_of_available_storage
       @size_of_available_storage = size_of_available_storage
 
-      mail(
+      mail_with_locale(
         bcc: recipients,
         subject: s_("NamespaceStorage|Action required: Approximately %{percentage_of_available_storage}%% of namespace storage remains for %{namespace_name}" %
                     { percentage_of_available_storage: percentage_of_available_storage, namespace_name: namespace.name })
diff --git a/ee/app/mailers/emails/user_cap.rb b/ee/app/mailers/emails/user_cap.rb
index e9afd1bca6be9fcfc49be665fa01121081879e14..0103d6631110d77b23427b312b2cf7c80b0904ae 100644
--- a/ee/app/mailers/emails/user_cap.rb
+++ b/ee/app/mailers/emails/user_cap.rb
@@ -13,7 +13,7 @@ def user_cap_reached(user_id)
       @url_to_docs = 'https://docs.gitlab.com/'
       @url_to_support = 'https://about.gitlab.com/support/'
 
-      mail to: email, subject: s_('AdminUsers|Important information about usage on your GitLab instance')
+      mail_with_locale to: email, subject: s_('AdminUsers|Important information about usage on your GitLab instance')
     end
   end
 end
diff --git a/ee/app/mailers/license_mailer.rb b/ee/app/mailers/license_mailer.rb
index 40501ca06b7ac2bcbd44e13ce2f6e74123256a61..b39c6c53c23e3f75c351e556ab9079434fdac6b9 100644
--- a/ee/app/mailers/license_mailer.rb
+++ b/ee/app/mailers/license_mailer.rb
@@ -10,7 +10,7 @@ def approaching_active_user_count_limit(recipients)
 
     return unless @license
 
-    mail(
+    mail_with_locale(
       bcc: recipients,
       subject: "Your subscription is nearing its user limit"
     )
diff --git a/ee/spec/mailers/license_mailer_spec.rb b/ee/spec/mailers/license_mailer_spec.rb
index 1e8dc7435d534ebc51903c08a924b440f2104239..c60180472bed0a6e69d1585a4d58ed6e1485ad21 100644
--- a/ee/spec/mailers/license_mailer_spec.rb
+++ b/ee/spec/mailers/license_mailer_spec.rb
@@ -34,5 +34,16 @@
         expect { subject }.not_to change(ActionMailer::Base.deliveries, :count)
       end
     end
+
+    context 'when send with I18n.default_locale' do
+      let(:users) { [create(:user, preferred_language: :zh_CN, email: '123@abc'), create(:user, preferred_language: :zh_CN, email: 'hjk@123')] }
+      let(:recipients) { [users[0].email, users[1].email] }
+
+      it { is_expected.to have_subject subject_text }
+      it { is_expected.to bcc_to recipients }
+      it { is_expected.to have_body_text "your subscription #{subscription_name}" }
+      it { is_expected.to have_body_text "You have #{active_user_count} active users" }
+      it { is_expected.to have_body_text "the user limit of #{license.restricted_user_count}" }
+    end
   end
 end
diff --git a/lib/gitlab/background_migration/mailers/unconfirm_mailer.rb b/lib/gitlab/background_migration/mailers/unconfirm_mailer.rb
index 3605b157f4f174e360526e6aebb39eb853e4e532..2bf631c6c7dc506bea34e3c94cf0c0a3a0bf17fe 100644
--- a/lib/gitlab/background_migration/mailers/unconfirm_mailer.rb
+++ b/lib/gitlab/background_migration/mailers/unconfirm_mailer.rb
@@ -11,7 +11,7 @@ def unconfirm_notification_email(user)
           @user = user
           @verification_from_mail = Gitlab.config.gitlab.email_from
 
-          mail(
+          mail_with_locale(
             template_path: 'unconfirm_mailer',
             template_name: 'unconfirm_notification_email',
             to: @user.notification_email_or_default,
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 8beb54bca4d3d61228f307191298ed21f40b8d78..1f53c472c5c3720a486dfb6ead8f0b95553fd009 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -167,6 +167,17 @@
             is_expected.to have_header('X-GitLab-NotificationReason', NotificationReason::ASSIGNED)
           end
         end
+
+        context 'when sent with a non default locale' do
+          let(:email_obj) { create(:email, :confirmed, user_id: recipient.id, email: '123@abc') }
+          let(:recipient) { create(:user, preferred_language: :zh_CN) }
+
+          it 'is translated into zh_CN' do
+            recipient.notification_email = email_obj.email
+            recipient.save!
+            is_expected.to have_body_text '指派人从 <strong>Previous Assignee</strong> 更改为 <strong>John Doe</strong>'
+          end
+        end
       end
 
       describe 'that have been relabeled' do
diff --git a/spec/mailers/repository_check_mailer_spec.rb b/spec/mailers/repository_check_mailer_spec.rb
index 8b1bc33d8bed66aeba934c485a432acd043036f3..5edd9c2d023ad45bdfad90a82587168b0605be51 100644
--- a/spec/mailers/repository_check_mailer_spec.rb
+++ b/spec/mailers/repository_check_mailer_spec.rb
@@ -14,6 +14,15 @@
       expect(mail).to deliver_to admins.map(&:email)
     end
 
+    it 'email with I18n.default_locale' do
+      admins = [create(:admin, preferred_language: :zh_CN), create(:admin, preferred_language: :zh_CN)]
+
+      mail = described_class.notify(3)
+
+      expect(mail).to deliver_to admins.map(&:email)
+      expect(mail).to have_subject 'GitLab Admin | 3 projects failed their last repository check'
+    end
+
     it 'omits blocked admins' do
       blocked = create(:admin, :blocked)
       admins = create_list(:admin, 3)