diff --git a/native/backup/use-client-backup.js b/native/backup/use-client-backup.js
--- a/native/backup/use-client-backup.js
+++ b/native/backup/use-client-backup.js
@@ -2,13 +2,15 @@
 
 import * as React from 'react';
 
+import { useInvalidCSATLogOut } from 'lib/actions/user-actions.js';
 import { isLoggedIn } from 'lib/selectors/user-selectors.js';
 import {
-  latestBackupInfoResponseValidator,
   type LatestBackupInfo,
+  latestBackupInfoResponseValidator,
   type UserKeys,
   userKeysResponseValidator,
 } from 'lib/types/backup-types.js';
+import { getMessageForException } from 'lib/utils/errors.js';
 import { assertWithValidator } from 'lib/utils/validation-utils.js';
 
 import { useGetBackupSecretForLoggedInUser } from './use-get-backup-secret.js';
@@ -53,14 +55,31 @@
   const loggedIn = useSelector(isLoggedIn);
   const getBackupSecret = useGetBackupSecretForLoggedInUser();
 
+  const invalidTokenLogOut = useInvalidCSATLogOut();
+  const authVerifiedEndpoint: <T>(backupCallPromise: Promise<T>) => Promise<T> =
+    React.useCallback(
+      async backupCallPromise => {
+        try {
+          return await backupCallPromise;
+        } catch (e) {
+          const message = getMessageForException(e);
+          if (message === 'Unauthenticated') {
+            void invalidTokenLogOut();
+          }
+          throw e;
+        }
+      },
+      [invalidTokenLogOut],
+    );
+
   const createFullBackup = React.useCallback(async () => {
     if (!loggedIn || !currentUserID) {
       throw new Error('Attempt to upload backup for not logged in user.');
     }
 
     const backupSecret = await getBackupSecret();
-    return commCoreModule.createFullBackup(backupSecret);
-  }, [loggedIn, currentUserID, getBackupSecret]);
+    return authVerifiedEndpoint(commCoreModule.createFullBackup(backupSecret));
+  }, [loggedIn, currentUserID, getBackupSecret, authVerifiedEndpoint]);
 
   const createUserKeysBackup = React.useCallback(async () => {
     if (!loggedIn || !currentUserID) {
@@ -68,8 +87,10 @@
     }
 
     const backupSecret = await getBackupSecret();
-    return commCoreModule.createUserKeysBackup(backupSecret);
-  }, [loggedIn, currentUserID, getBackupSecret]);
+    return authVerifiedEndpoint(
+      commCoreModule.createUserKeysBackup(backupSecret),
+    );
+  }, [loggedIn, currentUserID, getBackupSecret, authVerifiedEndpoint]);
 
   const retrieveLatestBackupInfo = React.useCallback(async () => {
     if (!loggedIn || !currentUserID || !currentUserInfo?.username) {
diff --git a/native/native_rust_library/src/backup/upload_handler.rs b/native/native_rust_library/src/backup/upload_handler.rs
--- a/native/native_rust_library/src/backup/upload_handler.rs
+++ b/native/native_rust_library/src/backup/upload_handler.rs
@@ -240,11 +240,12 @@
       siwe_backup_msg,
     };
 
-    backup_client
+    let result = backup_client
       .upload_backup(user_identity, backup_data)
-      .await?;
+      .await
+      .map_err(|e| e.to_string());
 
-    compaction_upload_promises::resolve(&backup_id, Ok(()));
+    compaction_upload_promises::resolve(&backup_id, result);
     tokio::spawn(cleanup_files(backup_id));
 
     Ok(())
diff --git a/shared/backup_client/src/lib.rs b/shared/backup_client/src/lib.rs
--- a/shared/backup_client/src/lib.rs
+++ b/shared/backup_client/src/lib.rs
@@ -12,7 +12,7 @@
 use reqwest::{
   header::InvalidHeaderValue,
   multipart::{Form, Part},
-  Body,
+  Body, StatusCode,
 };
 use serde::{Deserialize, Serialize};
 use sha2::{Digest, Sha256};
@@ -96,6 +96,13 @@
       .send()
       .await?;
 
+    if matches!(
+      response.status(),
+      StatusCode::UNAUTHORIZED | StatusCode::FORBIDDEN
+    ) {
+      return Err(Error::Unauthenticated);
+    }
+
     response.error_for_status()?;
 
     Ok(())