diff --git a/gix/src/commit.rs b/gix/src/commit.rs
index ad191f64a4a..d9c8d635ba6 100644
--- a/gix/src/commit.rs
+++ b/gix/src/commit.rs
@@ -1,6 +1,8 @@
 //!
 #![allow(clippy::empty_docs)]
 
+use std::convert::Infallible;
+
 /// An empty array of a type usable with the `gix::easy` API to help declaring no parents should be used
 pub const NO_PARENT_IDS: [gix_hash::ObjectId; 0] = [];
 
@@ -22,6 +24,12 @@ pub enum Error {
     ReferenceEdit(#[from] crate::reference::edit::Error),
 }
 
+impl From<std::convert::Infallible> for Error {
+    fn from(_value: Infallible) -> Self {
+        unreachable!("cannot be invoked")
+    }
+}
+
 ///
 #[cfg(feature = "revision")]
 pub mod describe {
diff --git a/gix/src/remote/connection/fetch/update_refs/mod.rs b/gix/src/remote/connection/fetch/update_refs/mod.rs
index bb3c4f5e379..640b028865e 100644
--- a/gix/src/remote/connection/fetch/update_refs/mod.rs
+++ b/gix/src/remote/connection/fetch/update_refs/mod.rs
@@ -102,6 +102,8 @@ pub(crate) fn update(
                 let update = if is_implicit_tag {
                     Mode::ImplicitTagNotSentByRemote.into()
                 } else {
+                    // Assure the ODB is not to blame for the missing object.
+                    repo.try_find_object(remote_id)?;
                     Mode::RejectedSourceObjectNotFound { id: remote_id.into() }.into()
                 };
                 updates.push(update);
diff --git a/gix/src/remote/connection/fetch/update_refs/update.rs b/gix/src/remote/connection/fetch/update_refs/update.rs
index 741fc12f5ba..f5adb348e2a 100644
--- a/gix/src/remote/connection/fetch/update_refs/update.rs
+++ b/gix/src/remote/connection/fetch/update_refs/update.rs
@@ -23,6 +23,8 @@ mod error {
         PeelToId(#[from] crate::reference::peel::Error),
         #[error("Failed to follow a symbolic reference to assure worktree isn't affected")]
         FollowSymref(#[from] gix_ref::file::find::existing::Error),
+        #[error(transparent)]
+        FindObject(#[from] crate::object::find::Error),
     }
 }
 
diff --git a/gix/tests/gix/remote/fetch.rs b/gix/tests/gix/remote/fetch.rs
index aa4d75f6241..671bba74783 100644
--- a/gix/tests/gix/remote/fetch.rs
+++ b/gix/tests/gix/remote/fetch.rs
@@ -14,6 +14,7 @@ mod shallow {
 mod blocking_and_async_io {
     use std::sync::atomic::AtomicBool;
 
+    use gix::config::tree::User;
     use gix::{
         config::tree::Protocol,
         remote::{fetch, fetch::Status, Direction::Fetch},
@@ -85,6 +86,73 @@ mod blocking_and_async_io {
         try_repo_rw(name).unwrap()
     }
 
+    #[test]
+    #[cfg(feature = "blocking-network-client")]
+    fn fetch_more_packs_than_can_be_handled() -> gix_testtools::Result {
+        use gix::interrupt::IS_INTERRUPTED;
+        use gix_odb::store::init::Slots;
+        use gix_testtools::tempfile;
+        fn create_empty_commit(repo: &gix::Repository) -> anyhow::Result<()> {
+            let name = repo.head_name()?.expect("no detached head");
+            repo.commit(
+                name.as_bstr(),
+                "empty",
+                gix::hash::ObjectId::empty_tree(repo.object_hash()),
+                repo.try_find_reference(name.as_ref())?.map(|r| r.id()),
+            )?;
+            Ok(())
+        }
+        for max_packs in 1..=3 {
+            let remote_dir = tempfile::tempdir()?;
+            let mut remote_repo = gix::init_bare(remote_dir.path())?;
+            {
+                let mut config = remote_repo.config_snapshot_mut();
+                config.set_value(&User::NAME, "author")?;
+                config.set_value(&User::EMAIL, "email@example.com")?;
+            }
+            create_empty_commit(&remote_repo)?;
+
+            let local_dir = tempfile::tempdir()?;
+            let (local_repo, _) = gix::clone::PrepareFetch::new(
+                remote_repo.path(),
+                local_dir.path(),
+                gix::create::Kind::Bare,
+                Default::default(),
+                gix::open::Options::isolated().object_store_slots(Slots::Given(max_packs)),
+            )?
+            .fetch_only(gix::progress::Discard, &IS_INTERRUPTED)?;
+
+            let remote = local_repo
+                .branch_remote(
+                    local_repo.head_ref()?.expect("branch available").name().shorten(),
+                    Fetch,
+                )
+                .expect("remote is configured after clone")?;
+            for _round_to_create_pack in 1..12 {
+                create_empty_commit(&remote_repo)?;
+                match remote
+                    .connect(Fetch)?
+                    .prepare_fetch(gix::progress::Discard, Default::default())?
+                    .receive(gix::progress::Discard, &IS_INTERRUPTED)
+                {
+                    Ok(out) => {
+                        for local_tracking_branch_name in out.ref_map.mappings.into_iter().filter_map(|m| m.local) {
+                            let r = local_repo.find_reference(&local_tracking_branch_name)?;
+                            r.id()
+                                .object()
+                                .expect("object should be present after fetching, triggering pack refreshes works");
+                            local_repo.head_ref()?.unwrap().set_target_id(r.id(), "post fetch")?;
+                        }
+                    }
+                    Err(err) => assert!(err
+                        .to_string()
+                        .starts_with("The slotmap turned out to be too small with ")),
+                }
+            }
+        }
+        Ok(())
+    }
+
     #[test]
     #[cfg(feature = "blocking-network-client")]
     #[allow(clippy::result_large_err)]