diff --git a/keyserver/src/services/blob.js b/keyserver/src/services/blob.js
--- a/keyserver/src/services/blob.js
+++ b/keyserver/src/services/blob.js
@@ -13,6 +13,7 @@
 } from 'lib/utils/blob-service.js';
 import { createHTTPAuthorizationHeader } from 'lib/utils/services-utils.js';
 
+import { clearIdentityInfo } from '../user/identity.js';
 import { verifyUserLoggedIn } from '../user/login.js';
 import { getContentSigningKey } from '../utils/olm-utils.js';
 
@@ -46,7 +47,11 @@
 ): Promise<BlobOperationResult> {
   const { hash: blobHash, holder } = params;
   const headers = await createRequestHeaders();
-  return assignBlobHolder({ blobHash, holder }, headers);
+  const assignResult = await assignBlobHolder({ blobHash, holder }, headers);
+  if (!assignResult.success && assignResult.reason === 'INVALID_CSAT') {
+    await clearIdentityInfo();
+  }
+  return assignResult;
 }
 
 async function uploadBlobKeyserverWrapper(
@@ -54,7 +59,11 @@
   hash: string,
 ): Promise<BlobOperationResult> {
   const authHeaders = await createRequestHeaders(false);
-  return uploadBlob(blob, hash, authHeaders);
+  const uploadResult = await uploadBlob(blob, hash, authHeaders);
+  if (!uploadResult.success && uploadResult.reason === 'INVALID_CSAT') {
+    await clearIdentityInfo();
+  }
+  return uploadResult;
 }
 
 async function upload(
@@ -108,7 +117,14 @@
 async function deleteBlob(params: BlobDescriptor, instant?: boolean) {
   const { hash: blobHash, holder } = params;
   const headers = await createRequestHeaders();
-  await removeBlobHolder({ blobHash, holder }, headers, instant);
+  const removeResult = await removeBlobHolder(
+    { blobHash, holder },
+    headers,
+    instant,
+  );
+  if (!removeResult.success && removeResult.reason === 'INVALID_CSAT') {
+    await clearIdentityInfo();
+  }
 }
 
 async function removeBlobHolders(holders: $ReadOnlyArray<BlobHashAndHolder>) {
diff --git a/lib/actions/upload-actions.js b/lib/actions/upload-actions.js
--- a/lib/actions/upload-actions.js
+++ b/lib/actions/upload-actions.js
@@ -32,7 +32,10 @@
 } from '../utils/blob-service.js';
 import { getMessageForException } from '../utils/errors.js';
 import { useDispatch } from '../utils/redux-utils.js';
-import { createDefaultHTTPRequestHeaders } from '../utils/services-utils.js';
+import {
+  createDefaultHTTPRequestHeaders,
+  errorMessageIsInvalidCSAT,
+} from '../utils/services-utils.js';
 
 export type MultimediaUploadCallbacks = Partial<{
   +onProgress: (percent: number) => void,
@@ -129,6 +132,9 @@
         defaultHeaders,
       );
       if (!assignHolderResult.success) {
+        if (assignHolderResult.reason === 'INVALID_CSAT') {
+          throw new Error('invalid_csat');
+        }
         const { status, statusText } = assignHolderResult;
         throw new Error(`Server responded with HTTP ${status}: ${statusText}`);
       }
@@ -136,6 +142,9 @@
         await assignHolderResult.response.json();
       blobAlreadyExists = dataExistsResponse;
     } catch (e) {
+      if (errorMessageIsInvalidCSAT(e)) {
+        throw e;
+      }
       throw new Error(
         `Failed to assign holder: ${
           getMessageForException(e) ?? 'unknown error'
@@ -162,6 +171,9 @@
           { ...callbacks },
         );
       } catch (e) {
+        if (errorMessageIsInvalidCSAT(e)) {
+          throw e;
+        }
         throw new Error(
           `Failed to upload blob: ${
             getMessageForException(e) ?? 'unknown error'
@@ -298,10 +310,16 @@
         defaultHeaders,
       );
       if (!assignHolderResult.success) {
+        if (assignHolderResult.reason === 'INVALID_CSAT') {
+          throw new Error('invalid_csat');
+        }
         const { status, statusText } = assignHolderResult;
         throw new Error(`Server responded with HTTP ${status}: ${statusText}`);
       }
     } catch (e) {
+      if (errorMessageIsInvalidCSAT(e)) {
+        throw e;
+      }
       throw new Error(
         `Failed to assign holder: ${
           getMessageForException(e) ?? 'unknown error'
diff --git a/lib/utils/blob-service-upload.js b/lib/utils/blob-service-upload.js
--- a/lib/utils/blob-service-upload.js
+++ b/lib/utils/blob-service-upload.js
@@ -53,6 +53,11 @@
       if (failed) {
         return;
       }
+      if (xhr.status === 401 || xhr.status === 403) {
+        failed = true;
+        reject(new Error('invalid_csat'));
+        return;
+      }
       resolve();
     };
     xhr.onabort = () => {
diff --git a/lib/utils/blob-service.js b/lib/utils/blob-service.js
--- a/lib/utils/blob-service.js
+++ b/lib/utils/blob-service.js
@@ -4,6 +4,7 @@
 import uuid from 'uuid';
 
 import { toBase64URL } from './base64.js';
+import { httpResponseIsInvalidCSAT } from './services-utils.js';
 import { replacePathParams, type URLPathParams } from './url-utils.js';
 import { assertWithValidator } from './validation-utils.js';
 import type { BlobServiceHTTPEndpoint } from '../facts/blob-service.js';
@@ -79,7 +80,7 @@
     }
   | {
       +success: false,
-      +reason: 'HASH_IN_USE' | 'OTHER',
+      +reason: 'HASH_IN_USE' | 'INVALID_CSAT' | 'OTHER',
       +status: number,
       +statusText: string,
     };
@@ -131,7 +132,14 @@
 
   if (!uploadBlobResponse.ok) {
     const { status, statusText } = uploadBlobResponse;
-    const reason = status === 409 ? 'HASH_IN_USE' : 'OTHER';
+
+    let reason = 'OTHER';
+    if (status === 409) {
+      reason = 'HASH_IN_USE';
+    } else if (httpResponseIsInvalidCSAT(uploadBlobResponse)) {
+      reason = 'INVALID_CSAT';
+    }
+
     return {
       success: false,
       reason,
@@ -165,7 +173,15 @@
 
   if (!response.ok) {
     const { status, statusText } = response;
-    return { success: false, reason: 'OTHER', status, statusText };
+    const reason = httpResponseIsInvalidCSAT(response)
+      ? 'INVALID_CSAT'
+      : 'OTHER';
+    return {
+      success: false,
+      reason,
+      status,
+      statusText,
+    };
   }
 
   return { success: true, response };
@@ -193,7 +209,15 @@
 
   if (!response.ok) {
     const { status, statusText } = response;
-    return { success: false, reason: 'OTHER', status, statusText };
+    const reason = httpResponseIsInvalidCSAT(response)
+      ? 'INVALID_CSAT'
+      : 'OTHER';
+    return {
+      success: false,
+      reason,
+      status,
+      statusText,
+    };
   }
 
   return { success: true, response };
diff --git a/lib/utils/services-utils.js b/lib/utils/services-utils.js
--- a/lib/utils/services-utils.js
+++ b/lib/utils/services-utils.js
@@ -2,6 +2,7 @@
 
 import base64 from 'base-64';
 
+import { getMessageForException } from './errors.js';
 import type { AuthMetadata } from '../shared/identity-client-context.js';
 
 // If this is true then we're using the identity service for auth. After we
@@ -40,6 +41,16 @@
   };
 }
 
+function httpResponseIsInvalidCSAT(response: Response): boolean {
+  const { status } = response;
+  return status === 401 || status === 403;
+}
+
+function errorMessageIsInvalidCSAT(exception: mixed): boolean {
+  const errorMessage = getMessageForException(exception);
+  return errorMessage === 'invalid_csat';
+}
+
 export {
   usingCommServicesAccessToken,
   supportingMultipleKeyservers,
@@ -47,4 +58,6 @@
   usingRestoreFlow,
   createHTTPAuthorizationHeader,
   createDefaultHTTPRequestHeaders,
+  httpResponseIsInvalidCSAT,
+  errorMessageIsInvalidCSAT,
 };