diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index d00963349..32d44f8e9 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -363,6 +363,7 @@
   "notificationPreview": "Preview",
   "recoveryPhraseEmpty": "Enter your recovery phrase",
   "displayNameEmpty": "Please enter a display name",
+  "displayNameTooLong": "Display name is too long",
   "members": "$count$ members",
   "activeMembers": "$count$ active members",
   "join": "Join",
diff --git a/ts/components/SessionWrapperModal.tsx b/ts/components/SessionWrapperModal.tsx
index 6b650900a..d808ad266 100644
--- a/ts/components/SessionWrapperModal.tsx
+++ b/ts/components/SessionWrapperModal.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useRef } from 'react';
+import React, { useRef } from 'react';
 import classNames from 'classnames';
 
 import { SessionIconButton } from './icon/';
@@ -63,17 +63,11 @@ export const SessionWrapperModal = (props: SessionWrapperModalType) => {
     }
   };
 
-  useEffect(() => {
-    document.addEventListener('mousedown', handleClick);
-
-    return () => {
-      document.removeEventListener('mousedown', handleClick);
-    };
-  }, []);
-
   return (
     <div
       className={classNames('loki-dialog modal', additionalClassName ? additionalClassName : null)}
+      onClick={handleClick}
+      role="dialog"
     >
       <div className="session-confirm-wrapper">
         <div ref={modalRef} className="session-modal">
diff --git a/ts/components/basic/SessionToast.tsx b/ts/components/basic/SessionToast.tsx
index 3231e3825..61db4b941 100644
--- a/ts/components/basic/SessionToast.tsx
+++ b/ts/components/basic/SessionToast.tsx
@@ -2,8 +2,8 @@ import React from 'react';
 
 import { Flex } from '../basic/Flex';
 import styled from 'styled-components';
-import { noop } from 'lodash';
 import { SessionIcon, SessionIconType } from '../icon';
+import { noop } from 'lodash';
 
 export enum SessionToastType {
   Info = 'info',
@@ -44,6 +44,8 @@ const IconDiv = styled.div`
   padding-inline-end: var(--margins-xs);
 `;
 
+// tslint:disable: use-simple-attributes
+
 export const SessionToast = (props: Props) => {
   const { title, description, type, icon } = props;
 
@@ -71,14 +73,10 @@ export const SessionToast = (props: Props) => {
     }
   }
 
+  const onToastClick = props?.onToastClick || noop;
+
   return (
-    // tslint:disable-next-line: use-simple-attributes
-    <Flex
-      container={true}
-      alignItems="center"
-      onClick={props?.onToastClick || noop}
-      data-testid="session-toast"
-    >
+    <Flex container={true} alignItems="center" onClick={onToastClick} data-testid="session-toast">
       <IconDiv>
         <SessionIcon iconType={toastIcon} iconSize={toastIconSize} />
       </IconDiv>
diff --git a/ts/components/dialog/EditProfileDialog.tsx b/ts/components/dialog/EditProfileDialog.tsx
index 69270fdd5..20af35eb7 100644
--- a/ts/components/dialog/EditProfileDialog.tsx
+++ b/ts/components/dialog/EditProfileDialog.tsx
@@ -16,12 +16,12 @@ import { uploadOurAvatar } from '../../interactions/conversationInteractions';
 import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
 import { SessionSpinner } from '../basic/SessionSpinner';
 import { SessionIconButton } from '../icon';
-import { MAX_USERNAME_LENGTH } from '../registration/RegistrationStages';
 import { SessionWrapperModal } from '../SessionWrapperModal';
 import { pickFileForAvatar } from '../../types/attachments/VisualAttachment';
 import { sanitizeSessionUsername } from '../../session/utils/String';
 import { setLastProfileUpdateTimestamp } from '../../util/storage';
 import { ConversationTypeEnum } from '../../models/conversationAttributes';
+import { MAX_USERNAME_BYTES } from '../../session/constants';
 
 interface State {
   profileName: string;
@@ -214,7 +214,7 @@ export class EditProfileDialog extends React.Component<{}, State> {
             value={this.state.profileName}
             placeholder={placeholderText}
             onChange={this.onNameEdited}
-            maxLength={MAX_USERNAME_LENGTH}
+            maxLength={MAX_USERNAME_BYTES}
             tabIndex={0}
             required={true}
             aria-required={true}
@@ -240,10 +240,18 @@ export class EditProfileDialog extends React.Component<{}, State> {
   }
 
   private onNameEdited(event: ChangeEvent<HTMLInputElement>) {
-    const newName = sanitizeSessionUsername(event.target.value);
-    this.setState({
-      profileName: newName,
-    });
+    const displayName = event.target.value;
+    try {
+      const newName = sanitizeSessionUsername(displayName);
+      this.setState({
+        profileName: newName,
+      });
+    } catch (e) {
+      this.setState({
+        profileName: displayName,
+      });
+      ToastUtils.pushToastError('nameTooLong', window.i18n('displayNameTooLong'));
+    }
   }
 
   private onKeyUp(event: any) {
@@ -266,26 +274,37 @@ export class EditProfileDialog extends React.Component<{}, State> {
    */
   private onClickOK() {
     const { newAvatarObjectUrl, profileName } = this.state;
-    const newName = profileName ? profileName.trim() : '';
+    try {
+      const newName = profileName ? profileName.trim() : '';
+
+      if (newName.length === 0 || newName.length > MAX_USERNAME_BYTES) {
+        return;
+      }
+
+      // this throw if the length in bytes is too long
+      const sanitizedName = sanitizeSessionUsername(newName);
+      const trimName = sanitizedName.trim();
+
+      this.setState(
+        {
+          profileName: trimName,
+          loading: true,
+        },
+        async () => {
+          await commitProfileEdits(newName, newAvatarObjectUrl);
+          this.setState({
+            loading: false,
+
+            mode: 'default',
+            updatedProfileName: this.state.profileName,
+          });
+        }
+      );
+    } catch (e) {
+      ToastUtils.pushToastError('nameTooLong', window.i18n('displayNameTooLong'));
 
-    if (newName.length === 0 || newName.length > MAX_USERNAME_LENGTH) {
       return;
     }
-
-    this.setState(
-      {
-        loading: true,
-      },
-      async () => {
-        await commitProfileEdits(newName, newAvatarObjectUrl);
-        this.setState({
-          loading: false,
-
-          mode: 'default',
-          updatedProfileName: this.state.profileName,
-        });
-      }
-    );
   }
 
   private closeDialog() {
diff --git a/ts/components/leftpane/ActionsPanel.tsx b/ts/components/leftpane/ActionsPanel.tsx
index a0cf34f39..ad1f782d2 100644
--- a/ts/components/leftpane/ActionsPanel.tsx
+++ b/ts/components/leftpane/ActionsPanel.tsx
@@ -39,7 +39,6 @@ import { getSwarmPollingInstance } from '../../session/apis/snode_api';
 import { forceRefreshRandomSnodePool } from '../../session/apis/snode_api/snodePool';
 import { Avatar, AvatarSize } from '../avatar/Avatar';
 import { SessionIconButton } from '../icon';
-import { SessionToastContainer } from '../SessionToastContainer';
 import { LeftPaneSectionContainer } from './LeftPaneSectionContainer';
 import { ipcRenderer } from 'electron';
 import { UserUtils } from '../../session/utils';
@@ -277,8 +276,6 @@ export const ActionsPanel = () => {
         <Section type={SectionType.Message} />
         <Section type={SectionType.Settings} />
 
-        <SessionToastContainer />
-
         <Section type={SectionType.PathIndicator} />
         <Section type={SectionType.Moon} />
       </LeftPaneSectionContainer>
diff --git a/ts/components/leftpane/LeftPane.tsx b/ts/components/leftpane/LeftPane.tsx
index fdeae0b7c..376719647 100644
--- a/ts/components/leftpane/LeftPane.tsx
+++ b/ts/components/leftpane/LeftPane.tsx
@@ -12,6 +12,7 @@ import { CallInFullScreenContainer } from '../calling/CallInFullScreenContainer'
 import { DraggableCallContainer } from '../calling/DraggableCallContainer';
 import { IncomingCallDialog } from '../calling/IncomingCallDialog';
 import { ModalContainer } from '../dialog/ModalContainer';
+import { SessionToastContainer } from '../SessionToastContainer';
 import { ActionsPanel } from './ActionsPanel';
 import { LeftPaneMessageSection } from './LeftPaneMessageSection';
 import { LeftPaneSettingSection } from './LeftPaneSettingSection';
@@ -71,6 +72,7 @@ export const LeftPane = () => {
       <div className="module-left-pane-session">
         <ModalContainer />
         <CallContainer />
+        <SessionToastContainer />
         <ActionsPanel />
 
         <StyledLeftPane className="module-left-pane">
diff --git a/ts/components/registration/RegistrationStages.tsx b/ts/components/registration/RegistrationStages.tsx
index 04e0ef7c6..9985552a2 100644
--- a/ts/components/registration/RegistrationStages.tsx
+++ b/ts/components/registration/RegistrationStages.tsx
@@ -17,7 +17,6 @@ import {
 import { fromHex } from '../../session/utils/String';
 import { setSignInByLinking, setSignWithRecoveryPhrase, Storage } from '../../util/storage';
 
-export const MAX_USERNAME_LENGTH = 26;
 // tslint:disable: use-simple-attributes
 
 export async function resetRegistration() {
diff --git a/ts/components/registration/RegistrationUserDetails.tsx b/ts/components/registration/RegistrationUserDetails.tsx
index 9f99f8026..dd56fe3c3 100644
--- a/ts/components/registration/RegistrationUserDetails.tsx
+++ b/ts/components/registration/RegistrationUserDetails.tsx
@@ -1,7 +1,7 @@
 import classNames from 'classnames';
 import React from 'react';
+import { MAX_USERNAME_BYTES } from '../../session/constants';
 import { SessionInput } from '../basic/SessionInput';
-import { MAX_USERNAME_LENGTH } from './RegistrationStages';
 
 const DisplayNameInput = (props: {
   stealAutoFocus?: boolean;
@@ -17,7 +17,7 @@ const DisplayNameInput = (props: {
       type="text"
       placeholder={window.i18n('enterDisplayName')}
       value={props.displayName}
-      maxLength={MAX_USERNAME_LENGTH}
+      maxLength={MAX_USERNAME_BYTES}
       onValueChanged={props.onDisplayNameChanged}
       onEnterPressed={props.handlePressEnter}
       inputDataTestId="display-name-input"
diff --git a/ts/components/registration/SignInTab.tsx b/ts/components/registration/SignInTab.tsx
index f0505c862..eec08d732 100644
--- a/ts/components/registration/SignInTab.tsx
+++ b/ts/components/registration/SignInTab.tsx
@@ -1,4 +1,5 @@
 import React, { useContext, useState } from 'react';
+import { ToastUtils } from '../../session/utils';
 import { sanitizeSessionUsername } from '../../session/utils/String';
 import { Flex } from '../basic/Flex';
 import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
@@ -95,6 +96,23 @@ const SignInButtons = (props: {
   );
 };
 
+export function sanitizeDisplayNameOrToast(
+  displayName: string,
+  setDisplayName: (sanitized: string) => void,
+  setDisplayNameError: (error: string | undefined) => void
+) {
+  try {
+    const sanitizedName = sanitizeSessionUsername(displayName);
+    const trimName = sanitizedName.trim();
+    setDisplayName(sanitizedName);
+    setDisplayNameError(!trimName ? window.i18n('displayNameEmpty') : undefined);
+  } catch (e) {
+    setDisplayName(displayName);
+    setDisplayNameError(window.i18n('displayNameTooLong'));
+    ToastUtils.pushToastError('toolong', window.i18n('displayNameTooLong'));
+  }
+}
+
 export const SignInTab = () => {
   const { setRegistrationPhase, signInMode, setSignInMode } = useContext(RegistrationContext);
 
@@ -148,10 +166,7 @@ export const SignInTab = () => {
             displayName={displayName}
             handlePressEnter={continueYourSession}
             onDisplayNameChanged={(name: string) => {
-              const sanitizedName = sanitizeSessionUsername(name);
-              const trimName = sanitizedName.trim();
-              setDisplayName(sanitizedName);
-              setDisplayNameError(!trimName ? window.i18n('displayNameEmpty') : undefined);
+              sanitizeDisplayNameOrToast(name, setDisplayName, setDisplayNameError);
             }}
             onSeedChanged={(seed: string) => {
               setRecoveryPhrase(seed);
diff --git a/ts/components/registration/SignUpTab.tsx b/ts/components/registration/SignUpTab.tsx
index 66dcefa78..586eb26a7 100644
--- a/ts/components/registration/SignUpTab.tsx
+++ b/ts/components/registration/SignUpTab.tsx
@@ -1,12 +1,11 @@
 import React, { useContext, useEffect, useState } from 'react';
-import { sanitizeSessionUsername } from '../../session/utils/String';
 import { Flex } from '../basic/Flex';
 import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
 import { SessionIdEditable } from '../basic/SessionIdEditable';
 import { SessionIconButton } from '../icon';
 import { RegistrationContext, RegistrationPhase, signUp } from './RegistrationStages';
 import { RegistrationUserDetails } from './RegistrationUserDetails';
-import { SignInMode } from './SignInTab';
+import { sanitizeDisplayNameOrToast, SignInMode } from './SignInTab';
 import { TermsAndConditions } from './TermsAndConditions';
 
 export enum SignUpMode {
@@ -144,10 +143,7 @@ export const SignUpTab = () => {
         displayName={displayName}
         handlePressEnter={signUpWithDetails}
         onDisplayNameChanged={(name: string) => {
-          const sanitizedName = sanitizeSessionUsername(name);
-          const trimName = sanitizedName.trim();
-          setDisplayName(sanitizedName);
-          setDisplayNameError(!trimName ? window.i18n('displayNameEmpty') : undefined);
+          sanitizeDisplayNameOrToast(name, setDisplayName, setDisplayNameError);
         }}
         stealAutoFocus={true}
       />
diff --git a/ts/session/constants.ts b/ts/session/constants.ts
index 9517c6a29..35bd981fb 100644
--- a/ts/session/constants.ts
+++ b/ts/session/constants.ts
@@ -60,3 +60,5 @@ export const UI = {
 export const QUOTED_TEXT_MAX_LENGTH = 150;
 
 export const DEFAULT_RECENT_REACTS = ['😂', '🥰', '😢', '😡', '😮', '😈'];
+
+export const MAX_USERNAME_BYTES = 64;
diff --git a/ts/session/utils/String.ts b/ts/session/utils/String.ts
index ba056fa81..b12f09971 100644
--- a/ts/session/utils/String.ts
+++ b/ts/session/utils/String.ts
@@ -1,4 +1,5 @@
 import ByteBuffer from 'bytebuffer';
+import { MAX_USERNAME_BYTES } from '../constants';
 
 export type Encoding = 'base64' | 'hex' | 'binary' | 'utf8';
 export type BufferType = ByteBuffer | Buffer | ArrayBuffer | Uint8Array;
@@ -54,10 +55,19 @@ const forbiddenDisplayCharRegex = /\uFFD2*/g;
  *
  * This function removes any forbidden char from a given display name.
  * This does not trim it as otherwise, a user cannot type User A as when he hits the space, it gets trimmed right away.
- * The trimming should hence happen after calling this and on saving the display name
+ * The trimming should hence happen after calling this and on saving the display name.
+ *
+ * This functions makes sure that the MAX_USERNAME_BYTES is verified for utf8 byte length
  * @param inputName the input to sanitize
  * @returns a sanitized string, untrimmed
  */
 export const sanitizeSessionUsername = (inputName: string) => {
-  return inputName.replace(forbiddenDisplayCharRegex, '');
+  const validChars = inputName.replace(forbiddenDisplayCharRegex, '');
+
+  const lengthBytes = encode(validChars, 'utf8').byteLength;
+  if (lengthBytes > MAX_USERNAME_BYTES) {
+    throw new Error('Display name is too long');
+  }
+
+  return validChars;
 };
diff --git a/ts/types/LocalizerKeys.ts b/ts/types/LocalizerKeys.ts
index 95e8907dd..2aa7aff76 100644
--- a/ts/types/LocalizerKeys.ts
+++ b/ts/types/LocalizerKeys.ts
@@ -495,6 +495,7 @@ export type LocalizerKeys =
   | 'trustThisContactDialogDescription'
   | 'unknownCountry'
   | 'searchFor...'
+  | 'displayNameTooLong'
   | 'joinedTheGroup'
   | 'editGroupName'
   | 'reportIssue';