diff --git a/tree/dataframe/inc/ROOT/RDF/RLoopManager.hxx b/tree/dataframe/inc/ROOT/RDF/RLoopManager.hxx
index a01c63a8e3bfde7ab23db77d1e356d08941a47b8..86bf32c3e06bd7043d97a19f59bb623bef0c0982 100644
--- a/tree/dataframe/inc/ROOT/RDF/RLoopManager.hxx
+++ b/tree/dataframe/inc/ROOT/RDF/RLoopManager.hxx
@@ -123,6 +123,7 @@ class RLoopManager : public RNodeBase {
    /// Cache of the tree/chain branch names. Never access directy, always use GetBranchNames().
    ColumnNames_t fValidBranchNames;
 
+   void CheckIndexedFriends();
    void RunEmptySourceMT();
    void RunEmptySource();
    void RunTreeProcessorMT();
diff --git a/tree/dataframe/src/RLoopManager.cxx b/tree/dataframe/src/RLoopManager.cxx
index cc875a8a08af2e01b570d12c6d3657cb229a61b1..22f02aad3cc8a988f834bda5fc53ed9ca2ddce9f 100644
--- a/tree/dataframe/src/RLoopManager.cxx
+++ b/tree/dataframe/src/RLoopManager.cxx
@@ -207,6 +207,25 @@ RLoopManager::RLoopManager(std::unique_ptr<RDataSource> ds, const ColumnNames_t
    fDataSource->SetNSlots(fNSlots);
 }
 
+// ROOT-9559: we cannot handle indexed friends
+void RLoopManager::CheckIndexedFriends()
+{
+   auto friends = fTree->GetListOfFriends();
+   if (!friends)
+      return;
+   for (auto friendElObj : *friends) {
+      auto friendEl = static_cast<TFriendElement *>(friendElObj);
+      auto friendTree = friendEl->GetTree();
+      if (friendTree && friendTree->GetTreeIndex()) {
+         std::string err = fTree->GetName();
+         err += " has a friend, \"";
+         err += friendTree->GetName();
+         err += "\", which has an index. This is not supported.";
+         throw std::runtime_error(err);
+      }
+   }
+}
+
 /// Run event loop with no source files, in parallel.
 void RLoopManager::RunEmptySourceMT()
 {
@@ -259,6 +278,7 @@ void RLoopManager::RunEmptySource()
 void RLoopManager::RunTreeProcessorMT()
 {
 #ifdef R__USE_IMT
+   CheckIndexedFriends();
    RSlotStack slotStack(fNSlots);
    const auto &entryList = fTree->GetEntryList() ? *fTree->GetEntryList() : TEntryList();
    auto tp = std::make_unique<ROOT::TTreeProcessorMT>(*fTree, entryList);
@@ -284,6 +304,7 @@ void RLoopManager::RunTreeProcessorMT()
 /// Run event loop over one or multiple ROOT files, in sequence.
 void RLoopManager::RunTreeReader()
 {
+   CheckIndexedFriends();
    TTreeReader r(fTree.get(), fTree->GetEntryList());
    if (0 == fTree->GetEntriesFast())
       return;
diff --git a/tree/dataframe/test/dataframe_friends.cxx b/tree/dataframe/test/dataframe_friends.cxx
index 685d86f33cd458fd4940d620aee640257938b9c4..ab7639c71a874ac3c4fc2913fab9e128b70d5d39 100644
--- a/tree/dataframe/test/dataframe_friends.cxx
+++ b/tree/dataframe/test/dataframe_friends.cxx
@@ -211,4 +211,76 @@ TEST_F(RDFAndFriends, FriendChainMT)
    ROOT::DisableImplicitMT();
 }
 
+// ROOT-9559
+void FillIndexedFriend(const char *mainfile, const char *auxfile)
+{
+   // Start by creating main Tree
+   TFile f(mainfile, "RECREATE");
+   TTree mainTree("mainTree", "mainTree");
+   int idx;
+   mainTree.Branch("idx", &idx);
+   float x;
+   mainTree.Branch("x", &x);
+
+   idx = 1;
+   x = 0.5;
+   mainTree.Fill();
+   idx = 1;
+   x = 2;
+   mainTree.Fill();
+   idx = 1;
+   x = 5;
+   mainTree.Fill();
+   idx = 2;
+   x = 1;
+   mainTree.Fill();
+   idx = 2;
+   x = 8;
+   mainTree.Fill();
+   mainTree.Write();
+   f.Close();
+
+   // And aux tree
+   TFile f2(auxfile, "RECREATE");
+   TTree auxTree("auxTree", "auxTree");
+   auxTree.Branch("idx", &idx);
+   float y;
+   auxTree.Branch("y", &y);
+   idx = 1;
+   y = 5;
+   auxTree.Fill();
+   idx = 2;
+   y = 7;
+   auxTree.Fill();
+   auxTree.Write();
+   f2.Close();
+}
+
+TEST(RDFAndFriendsNoFixture, IndexedFriend)
+{
+   auto mainFile = "IndexedFriend_main.root";
+   auto auxFile = "IndexedFriend_aux.root";
+   FillIndexedFriend(mainFile, auxFile);
+
+   TChain mainChain("mainTree", "mainTree");
+   mainChain.Add(mainFile);
+   TChain auxChain("auxTree", "auxTree");
+   auxChain.Add(auxFile);
+
+   auxChain.BuildIndex("idx");
+   mainChain.AddFriend(&auxChain);
+
+   int ret = 1;
+   try {
+      auto df = ROOT::RDataFrame(mainChain);
+      *df.Min<int>("x");
+   } catch (const std::runtime_error &) {
+      ret = 0;
+   }
+   EXPECT_EQ(0, ret);
+
+   gSystem->Unlink(mainFile);
+   gSystem->Unlink(auxFile);
+}
+
 #endif // R__USE_IMT