diff --git a/web/components/button.react.js b/web/components/button.react.js
--- a/web/components/button.react.js
+++ b/web/components/button.react.js
@@ -12,7 +12,7 @@
   | 'danger'
   | 'round';
 
-type Props = {
+export type ButtonProps = {
   +onClick: (event: SyntheticEvent<HTMLButtonElement>) => mixed,
   +children: React.Node,
   +variant?: ButtonVariant,
@@ -21,7 +21,7 @@
   +className?: string,
 };
 
-function Button(props: Props): React.Node {
+function Button(props: ButtonProps): React.Node {
   const {
     onClick,
     children,
diff --git a/web/modals/threads/settings/submit-section.css b/web/modals/threads/settings/submit-section.css
new file mode 100644
--- /dev/null
+++ b/web/modals/threads/settings/submit-section.css
@@ -0,0 +1,22 @@
+.container {
+  height: 100%;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+}
+
+.error {
+  text-align: center;
+  font-size: 16px;
+  color: var(--error);
+  font-style: italic;
+
+  margin-top: auto;
+  padding: 5px;
+}
+
+.button {
+  width: 100%;
+  align-self: flex-end;
+  min-height: 45px;
+}
diff --git a/web/modals/threads/settings/submit-section.react.js b/web/modals/threads/settings/submit-section.react.js
new file mode 100644
--- /dev/null
+++ b/web/modals/threads/settings/submit-section.react.js
@@ -0,0 +1,46 @@
+// @flow
+
+import classnames from 'classnames';
+import * as React from 'react';
+
+import type { ButtonProps } from '../../../components/button.react';
+import Button from '../../../components/button.react';
+import css from './submit-section.css';
+
+type Props = {
+  ...ButtonProps,
+  +errorMessage?: ?string,
+  +containerClassName?: string,
+};
+
+function SubmitSection(props: Props): React.Node {
+  const {
+    children,
+    containerClassName = '',
+    errorMessage,
+    onClick,
+    variant,
+    disabled = false,
+    className = '',
+  } = props;
+
+  const containerStyle = classnames(css.container, containerClassName);
+  const buttonStyle = classnames(css.button, className);
+
+  return (
+    <div className={containerStyle}>
+      <div className={css.error}>{errorMessage}</div>
+      <Button
+        type="submit"
+        className={buttonStyle}
+        onClick={onClick}
+        disabled={disabled}
+        variant={variant}
+      >
+        {children}
+      </Button>
+    </div>
+  );
+}
+
+export default SubmitSection;
diff --git a/web/modals/threads/settings/thread-settings-delete-tab.css b/web/modals/threads/settings/thread-settings-delete-tab.css
--- a/web/modals/threads/settings/thread-settings-delete-tab.css
+++ b/web/modals/threads/settings/thread-settings-delete-tab.css
@@ -19,13 +19,15 @@
   margin-bottom: 12px;
 }
 
+form.container {
+  display: flex;
+  flex-direction: column;
+  flex: 1;
+}
+
 .deletion_warning {
   font-weight: var(--bold);
   color: var(--fg);
   font-size: var(--s-font-14);
   margin-bottom: 16px;
 }
-
-.delete_button {
-  width: 100%;
-}
diff --git a/web/modals/threads/settings/thread-settings-delete-tab.react.js b/web/modals/threads/settings/thread-settings-delete-tab.react.js
--- a/web/modals/threads/settings/thread-settings-delete-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-delete-tab.react.js
@@ -13,16 +13,17 @@
   useServerCall,
 } from 'lib/utils/action-utils';
 
-import Button from '../../../components/button.react';
 import SWMansionIcon from '../../../SWMansionIcon.react';
 import Input from '../../input.react';
 import { useModalContext } from '../../modal-provider.react';
+import SubmitSection from './submit-section.react';
 import css from './thread-settings-delete-tab.css';
 
 type ThreadSettingsDeleteTabProps = {
   +threadSettingsOperationInProgress: boolean,
   +threadInfo: ThreadInfo,
-  +setErrorMessage: SetState<string>,
+  +setErrorMessage: SetState<?string>,
+  +errorMessage?: ?string,
 };
 
 function ThreadSettingsDeleteTab(
@@ -32,6 +33,7 @@
     threadSettingsOperationInProgress,
     threadInfo,
     setErrorMessage,
+    errorMessage,
   } = props;
 
   const modalContext = useModalContext();
@@ -83,7 +85,7 @@
   );
 
   return (
-    <form method="POST">
+    <form method="POST" className={css.container}>
       <div>
         <SWMansionIcon icon="warning-circle" size={22} />
         <p className={css.deletion_warning}>
@@ -107,16 +109,16 @@
           />
         </div>
       </div>
-      <Button
+      <SubmitSection
+        errorMessage={errorMessage}
         onClick={onDelete}
         variant="danger"
         disabled={
           threadSettingsOperationInProgress || accountPassword.length === 0
         }
-        className={css.delete_button}
       >
         Delete
-      </Button>
+      </SubmitSection>
     </form>
   );
 }
diff --git a/web/modals/threads/settings/thread-settings-general-tab.css b/web/modals/threads/settings/thread-settings-general-tab.css
--- a/web/modals/threads/settings/thread-settings-general-tab.css
+++ b/web/modals/threads/settings/thread-settings-general-tab.css
@@ -27,7 +27,8 @@
   margin-bottom: 12px;
 }
 
-.save_button {
-  width: 100%;
-  min-height: 46px;
+form.container {
+  display: flex;
+  flex-direction: column;
+  flex: 1;
 }
diff --git a/web/modals/threads/settings/thread-settings-general-tab.react.js b/web/modals/threads/settings/thread-settings-general-tab.react.js
--- a/web/modals/threads/settings/thread-settings-general-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-general-tab.react.js
@@ -20,10 +20,10 @@
 } from 'lib/utils/action-utils';
 import { firstLine } from 'lib/utils/string-utils';
 
-import Button from '../../../components/button.react';
 import LoadingIndicator from '../../../loading-indicator.react';
 import Input from '../../input.react';
 import ColorSelector from '../color-selector.react';
+import SubmitSection from './submit-section.react';
 import css from './thread-settings-general-tab.css';
 
 type ThreadSettingsGeneralTabProps = {
@@ -32,7 +32,8 @@
   +threadNamePlaceholder: string,
   +queuedChanges: ThreadChanges,
   +setQueuedChanges: SetState<ThreadChanges>,
-  +setErrorMessage: SetState<string>,
+  +setErrorMessage: SetState<?string>,
+  +errorMessage?: ?string,
 };
 function ThreadSettingsGeneralTab(
   props: ThreadSettingsGeneralTabProps,
@@ -44,6 +45,7 @@
     queuedChanges,
     setQueuedChanges,
     setErrorMessage,
+    errorMessage,
   } = props;
 
   const dispatchActionPromise = useDispatchActionPromise();
@@ -145,7 +147,7 @@
   }, [threadSettingsOperationInProgress]);
 
   return (
-    <form method="POST">
+    <form method="POST" className={css.container}>
       <div>
         <div className={css.form_title}>Chat name</div>
         <div className={css.form_content}>
@@ -182,14 +184,13 @@
           />
         </div>
       </div>
-      <Button
-        type="submit"
+      <SubmitSection
+        errorMessage={errorMessage}
         onClick={onSubmit}
         disabled={threadSettingsOperationInProgress || !changeQueued}
-        className={css.save_button}
       >
         {saveButtonContent}
-      </Button>
+      </SubmitSection>
     </form>
   );
 }
diff --git a/web/modals/threads/settings/thread-settings-modal.css b/web/modals/threads/settings/thread-settings-modal.css
--- a/web/modals/threads/settings/thread-settings-modal.css
+++ b/web/modals/threads/settings/thread-settings-modal.css
@@ -2,18 +2,24 @@
   display: flex;
   flex-direction: column;
   width: 383px;
-  height: 539px;
+  height: 560px;
   overflow: hidden;
 }
 div.tab_body {
   padding: 20px;
   overflow: auto;
+  flex: 1;
+  display: flex;
+  flex-direction: column;
 }
 div.modal_form_error {
   display: flex;
+  align-items: flex-end;
   justify-content: center;
-  padding-top: 8px;
-  font-size: 16px;
-  color: red;
+  font-size: var(--s-font-16);
+  color: var(--error);
   font-style: italic;
+  min-height: 26px;
+  flex: 1;
+  padding: 5px;
 }
diff --git a/web/modals/threads/settings/thread-settings-modal.react.js b/web/modals/threads/settings/thread-settings-modal.react.js
--- a/web/modals/threads/settings/thread-settings-modal.react.js
+++ b/web/modals/threads/settings/thread-settings-modal.react.js
@@ -59,7 +59,7 @@
       state => threadInfoSelector(state)[props.threadID],
     );
     const modalContext = useModalContext();
-    const [errorMessage, setErrorMessage] = React.useState('');
+    const [errorMessage, setErrorMessage] = React.useState<?string>('');
     const [currentTabType, setCurrentTabType] = React.useState<TabType>(
       'general',
     );
@@ -144,8 +144,8 @@
             queuedChanges={queuedChanges}
             setQueuedChanges={setQueuedChanges}
             setErrorMessage={setErrorMessage}
+            errorMessage={errorMessage}
           />
-          <div className={css.modal_form_error}>{errorMessage}</div>
         </div>
       </Tabs.Item>,
     ];
@@ -169,8 +169,8 @@
               queuedChanges={queuedChanges}
               setQueuedChanges={setQueuedChanges}
               setErrorMessage={setErrorMessage}
+              errorMessage={errorMessage}
             />
-            <div className={css.modal_form_error}>{errorMessage}</div>
           </div>
         </Tabs.Item>,
       );
@@ -200,8 +200,8 @@
               threadSettingsOperationInProgress={changeInProgress}
               threadInfo={threadInfo}
               setErrorMessage={setErrorMessage}
+              errorMessage={errorMessage}
             />
-            <div className={css.modal_form_error}>{errorMessage}</div>
           </div>
         </Tabs.Item>,
       );
diff --git a/web/modals/threads/settings/thread-settings-privacy-tab.css b/web/modals/threads/settings/thread-settings-privacy-tab.css
--- a/web/modals/threads/settings/thread-settings-privacy-tab.css
+++ b/web/modals/threads/settings/thread-settings-privacy-tab.css
@@ -8,6 +8,8 @@
   padding: 12px 0;
 }
 
-.save_button {
-  width: 100%;
+form.container {
+  display: flex;
+  flex-direction: column;
+  flex: 1;
 }
diff --git a/web/modals/threads/settings/thread-settings-privacy-tab.react.js b/web/modals/threads/settings/thread-settings-privacy-tab.react.js
--- a/web/modals/threads/settings/thread-settings-privacy-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-privacy-tab.react.js
@@ -18,10 +18,10 @@
   useServerCall,
 } from 'lib/utils/action-utils';
 
-import Button from '../../../components/button.react';
 import EnumSettingsOption from '../../../components/enum-settings-option.react';
 import SWMansionIcon from '../../../SWMansionIcon.react';
 import { useModalContext } from '../../modal-provider.react';
+import SubmitSection from './submit-section.react';
 import css from './thread-settings-privacy-tab.css';
 
 const { COMMUNITY_OPEN_SUBTHREAD, COMMUNITY_SECRET_SUBTHREAD } = threadTypes;
@@ -47,7 +47,8 @@
   +threadInfo: ThreadInfo,
   +queuedChanges: ThreadChanges,
   +setQueuedChanges: SetState<ThreadChanges>,
-  +setErrorMessage: SetState<string>,
+  +setErrorMessage: SetState<?string>,
+  +errorMessage?: ?string,
 };
 function ThreadSettingsPrivacyTab(
   props: ThreadSettingsPrivacyTabProps,
@@ -58,6 +59,7 @@
     queuedChanges,
     setQueuedChanges,
     setErrorMessage,
+    errorMessage,
   } = props;
 
   const modalContext = useModalContext();
@@ -138,7 +140,7 @@
   );
 
   return (
-    <form method="POST">
+    <form method="POST" className={css.container}>
       <div className={css.form_title}>Chat type</div>
       <div className={css.enum_container}>
         <EnumSettingsOption
@@ -162,14 +164,13 @@
         />
       </div>
 
-      <Button
-        type="submit"
+      <SubmitSection
         onClick={onSubmit}
         disabled={threadSettingsOperationInProgress || !changeQueued}
-        className={css.save_button}
+        errorMessage={errorMessage}
       >
         Save
-      </Button>
+      </SubmitSection>
     </form>
   );
 }
diff --git a/web/modals/threads/settings/thread-settings-relationship-button.react.js b/web/modals/threads/settings/thread-settings-relationship-button.react.js
--- a/web/modals/threads/settings/thread-settings-relationship-button.react.js
+++ b/web/modals/threads/settings/thread-settings-relationship-button.react.js
@@ -40,7 +40,7 @@
 type ButtonProps = {
   +relationshipButton: RelationshipButton,
   +otherUserInfo: UserInfo,
-  +setErrorMessage?: SetState<string>,
+  +setErrorMessage?: SetState<?string>,
 };
 
 function ThreadSettingsRelationshipButton(props: ButtonProps): React.Node {
diff --git a/web/modals/threads/settings/thread-settings-relationship-tab.react.js b/web/modals/threads/settings/thread-settings-relationship-tab.react.js
--- a/web/modals/threads/settings/thread-settings-relationship-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-relationship-tab.react.js
@@ -10,7 +10,7 @@
 import css from './thread-settings-relationship-tab.css';
 
 type Props = {
-  +setErrorMessage: SetState<string>,
+  +setErrorMessage: SetState<?string>,
   +relationshipButtons: $ReadOnlyArray<RelationshipButton>,
   +otherUserInfo: UserInfo,
 };