diff --git a/ui/page/livestreamSetup/view.jsx b/ui/page/livestreamSetup/view.jsx
index eb6da5a23..61ead7329 100644
--- a/ui/page/livestreamSetup/view.jsx
+++ b/ui/page/livestreamSetup/view.jsx
@@ -15,6 +15,7 @@ import CopyableText from 'component/copyableText';
 import Card from 'component/common/card';
 import ClaimList from 'component/claimList';
 import usePersistedState from 'effects/use-persisted-state';
+import usePrevious from 'effects/use-previous';
 
 type Props = {
   channels: Array<ChannelClaim>,
@@ -50,8 +51,116 @@ export default function LivestreamSetupPage(props: Props) {
           claim.value_type === 'stream' && !(claim.value && claim.value.source)
       )
     : [];
+  const [localPending, setLocalPending] = React.useState([]); //
+  const localPendingStr = JSON.stringify(localPending);
+  const pendingLivestreamClaimsStr = JSON.stringify(pendingLiveStreamClaims);
+  const prevPendingLiveStreamClaimStr = usePrevious(pendingLivestreamClaimsStr);
+  const liveStreamClaimsStr = JSON.stringify(livestreamClaims);
+  const prevLiveStreamClaimsStr = JSON.stringify(liveStreamClaimsStr);
   const pendingLength = pendingLiveStreamClaims.length;
-  const totalLivestreamClaims = pendingLiveStreamClaims.concat(livestreamClaims);
+
+  // maintain a pendingClaims list by channelId that locally that things are removed from only when they show up in claim_search results.
+
+  React.useEffect(() => {
+    if (activeChannelClaimStr) {
+      const channelClaim = JSON.parse(activeChannelClaimStr);
+
+      // ensure we have a channel
+      if (channelClaim.claim_id) {
+        Lbry.channel_sign({
+          channel_id: channelClaim.claim_id,
+          hexdata: toHex(channelClaim.name),
+        })
+          .then((data) => {
+            setSigData(data);
+          })
+          .catch((error) => {
+            setSigData({ signature: null, signing_ts: null });
+          });
+      }
+    }
+  }, [activeChannelClaimStr, setSigData]);
+
+  // The following 2 effects handle the time between pending disappearing and claim_search being able to find it.
+  // We'll maintain our own pending list:
+  // add to it when there are new things in pending
+  // remove items only when our claim_search finds it
+  React.useEffect(() => {
+    // add to localPending when pending changes
+    const localPending = JSON.parse(localPendingStr);
+    const pendingLivestreamClaims = JSON.parse(pendingLivestreamClaimsStr);
+    if (
+      pendingLiveStreamClaims !== prevPendingLiveStreamClaimStr ||
+      (pendingLivestreamClaims.length && !localPending.length)
+    ) {
+      const prevPendingLivestreamClaims = prevPendingLiveStreamClaimStr
+        ? JSON.parse(prevPendingLiveStreamClaimStr)
+        : [];
+      const pendingClaimIds = pendingLivestreamClaims.map((claim) => claim.claim_id);
+      const prevPendingClaimIds = prevPendingLivestreamClaims.map((claim) => claim.claim_id);
+      const newLocalPending = [];
+      if (pendingClaimIds.length > prevPendingClaimIds.length) {
+        pendingLivestreamClaims.forEach((pendingClaim) => {
+          if (!localPending.some((lClaim) => lClaim.claim_id === pendingClaim.claim_id)) {
+            newLocalPending.push(pendingClaim);
+          }
+        });
+        setLocalPending(localPending.concat(newLocalPending));
+      }
+    }
+  }, [pendingLivestreamClaimsStr, prevPendingLiveStreamClaimStr, localPendingStr, setLocalPending]);
+
+  React.useEffect(() => {
+    // remove from localPending when livestreamClaims found
+    const localPending = JSON.parse(localPendingStr);
+    if (liveStreamClaimsStr !== prevLiveStreamClaimsStr && localPending.length) {
+      const livestreamClaims = JSON.parse(liveStreamClaimsStr);
+      setLocalPending(
+        localPending.filter((pending) => !livestreamClaims.some((claim) => claim.claim_id === pending.claim_id))
+      );
+    }
+  }, [liveStreamClaimsStr, prevLiveStreamClaimsStr, localPendingStr, setLocalPending]);
+
+  React.useEffect(() => {
+    let checkClaimsInterval;
+    if (!activeChannelClaimStr) return;
+    const channelClaim = JSON.parse(activeChannelClaimStr);
+
+    function checkLivestreamClaims() {
+      Lbry.claim_search({
+        channel_ids: [channelClaim.claim_id],
+        has_no_source: true,
+        claim_type: ['stream'],
+      })
+        .then((res) => {
+          if (res && res.items && res.items.length > 0) {
+            setLivestreamClaims(res.items.reverse());
+          } else {
+            setLivestreamClaims([]);
+          }
+          setSpin(false);
+        })
+        .catch(() => {
+          setLivestreamClaims([]);
+          setSpin(false);
+        });
+    }
+    if (!checkClaimsInterval) {
+      checkLivestreamClaims();
+      checkClaimsInterval = setInterval(checkLivestreamClaims, LIVESTREAM_CLAIM_POLL_IN_MS);
+    }
+    return () => {
+      if (checkClaimsInterval) {
+        clearInterval(checkClaimsInterval);
+      }
+    };
+  }, [activeChannelClaimStr, pendingLength, setSpin]);
+  const activeChannelId = activeChannelClaim && activeChannelClaim.claim_id;
+  const localPendingForChannel = localPending.filter(
+    (claim) => claim.signing_channel && claim.signing_channel.claim_id === activeChannelId
+  );
+  const totalLivestreamClaims = localPendingForChannel.concat(livestreamClaims);
+
   const helpText = (
     <div className="section__subtitle">
       <p>
@@ -95,61 +204,6 @@ export default function LivestreamSetupPage(props: Props) {
     </div>
   );
 
-  React.useEffect(() => {
-    if (activeChannelClaimStr) {
-      const channelClaim = JSON.parse(activeChannelClaimStr);
-
-      // ensure we have a channel
-      if (channelClaim.claim_id) {
-        Lbry.channel_sign({
-          channel_id: channelClaim.claim_id,
-          hexdata: toHex(channelClaim.name),
-        })
-          .then((data) => {
-            setSigData(data);
-          })
-          .catch((error) => {
-            setSigData({ signature: null, signing_ts: null });
-          });
-      }
-    }
-  }, [activeChannelClaimStr, setSigData]);
-
-  React.useEffect(() => {
-    let checkClaimsInterval;
-    if (!activeChannelClaimStr) return;
-    const channelClaim = JSON.parse(activeChannelClaimStr);
-
-    function checkLivestreamClaims() {
-      Lbry.claim_search({
-        channel_ids: [channelClaim.claim_id],
-        has_no_source: true,
-        claim_type: ['stream'],
-      })
-        .then((res) => {
-          if (res && res.items && res.items.length > 0) {
-            setLivestreamClaims(res.items.reverse());
-          } else {
-            setLivestreamClaims([]);
-          }
-          setSpin(false);
-        })
-        .catch(() => {
-          setLivestreamClaims([]);
-          setSpin(false);
-        });
-    }
-    if (!checkClaimsInterval) {
-      checkLivestreamClaims();
-      checkClaimsInterval = setInterval(checkLivestreamClaims, LIVESTREAM_CLAIM_POLL_IN_MS);
-    }
-    return () => {
-      if (checkClaimsInterval) {
-        clearInterval(checkClaimsInterval);
-      }
-    };
-  }, [activeChannelClaimStr, pendingLength, setSpin]);
-
   return (
     <Page>
       {(fetchingChannels || spin) && (
@@ -219,11 +273,11 @@ export default function LivestreamSetupPage(props: Props) {
 
             {totalLivestreamClaims.length > 0 ? (
               <>
-                {Boolean(pendingLiveStreamClaims.length) && (
+                {Boolean(localPendingForChannel.length) && (
                   <div className="section">
                     <ClaimList
                       header={__('Your pending livestream uploads')}
-                      uris={pendingLiveStreamClaims.map((claim) => claim.permanent_url)}
+                      uris={localPendingForChannel.map((claim) => claim.permanent_url)}
                     />
                   </div>
                 )}