diff --git a/cmdline/CtaAdminCmd.cpp b/cmdline/CtaAdminCmd.cpp
index ee87a4ed0f997daf50dac7ecac9dfd14e33d39b2..09337e79dd26e007c905b255cfc381fc4c0e0aef 100644
--- a/cmdline/CtaAdminCmd.cpp
+++ b/cmdline/CtaAdminCmd.cpp
@@ -215,6 +215,8 @@ void CtaAdminCmd::send() const
          if(!isJson()) switch(response.show_header()) {
             case HeaderType::ARCHIVEFILE_LS:               printAfLsHeader(); break;
             case HeaderType::ARCHIVEFILE_LS_SUMMARY:       printAfLsSummaryHeader(); break;
+            case HeaderType::FAILEDREQUEST_LS:             printFrLsHeader(); break;
+            case HeaderType::FAILEDREQUEST_LS_SUMMARY:     printFrLsSummaryHeader(); break;
             case HeaderType::LISTPENDINGARCHIVES:          printLpaHeader(); break;
             case HeaderType::LISTPENDINGARCHIVES_SUMMARY:  printLpaSummaryHeader(); break;
             case HeaderType::LISTPENDINGRETRIEVES:         printLprHeader(); break;
@@ -442,6 +444,37 @@ void CtaAdminCmd::print(const cta::admin::ArchiveFileLsSummary &afls_summary)
              << std::endl;
 }
 
+void CtaAdminCmd::printFrLsHeader()
+{
+   std::cout << TEXT_RED
+             << std::setfill(' ') << std::setw(11) << std::right << "request type"   << ' '
+             << std::setfill(' ') << std::setw(7)  << std::right << "copy no"        << ' '
+             << std::setfill(' ') << std::setw(7)  << std::right << "vid"            << ' '
+             << std::setfill(' ') << std::setw(8)  << std::right << "requester"      << ' '
+             << std::setfill(' ') << std::setw(8)  << std::right << "group"          << ' '
+                                                                 << "path"
+             << TEXT_NORMAL << std::endl;
+}
+
+void CtaAdminCmd::print(const cta::admin::FailedRequestLsItem &frls_item)
+{
+   throw std::runtime_error("Not implemented.");
+}
+
+void CtaAdminCmd::printFrLsSummaryHeader()
+{
+   std::cout << TEXT_RED
+             << std::setfill(' ') << std::setw(11) << std::right << "request type"   << ' '
+             << std::setfill(' ') << std::setw(13) << std::right << "total files" << ' '
+             << std::setfill(' ') << std::setw(12) << std::right << "total size"  << ' '
+             << TEXT_NORMAL << std::endl;
+}
+
+void CtaAdminCmd::print(const cta::admin::FailedRequestLsSummary &frls_summary)
+{
+   throw std::runtime_error("Not implemented.");
+}
+
 void CtaAdminCmd::printLpaHeader()
 {
    std::cout << TEXT_RED
diff --git a/cmdline/CtaAdminCmd.hpp b/cmdline/CtaAdminCmd.hpp
index 67dc8d16943ed6be70bc49b4f242c6498ed42c33..51d1f0ae56ca9b986988008458f1324a196c38ef 100644
--- a/cmdline/CtaAdminCmd.hpp
+++ b/cmdline/CtaAdminCmd.hpp
@@ -50,6 +50,8 @@ public:
    // Output headers
    static void printAfLsHeader();
    static void printAfLsSummaryHeader();
+   static void printFrLsHeader();
+   static void printFrLsSummaryHeader();
    static void printLpaHeader();
    static void printLpaSummaryHeader();
    static void printLprHeader();
@@ -59,6 +61,8 @@ public:
    // Output records
    static void print(const ArchiveFileLsItem &afls_item);
    static void print(const ArchiveFileLsSummary &afls_summary);
+   static void print(const FailedRequestLsItem &frls_item);
+   static void print(const FailedRequestLsSummary &frls_summary);
    static void print(const ListPendingArchivesItem &lpa_item);
    static void print(const ListPendingArchivesSummary &lpa_summary);
    static void print(const ListPendingRetrievesItem &lpr_item);
diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.cpp b/xroot_plugins/XrdSsiCtaRequestMessage.cpp
index 439bed5886ea91df46e2f96fb2f1212e10ce0323..70d560901589a42ac7d5ba48e315d4cdf9d9198f 100644
--- a/xroot_plugins/XrdSsiCtaRequestMessage.cpp
+++ b/xroot_plugins/XrdSsiCtaRequestMessage.cpp
@@ -1040,6 +1040,13 @@ void RequestMessage::processFailedRequest_Ls(const cta::admin::AdminCmd &admincm
 
    std::stringstream cmdlineOutput;
 
+   if(has_flag(OptionBoolean::JUSTARCHIVE) && has_flag(OptionBoolean::JUSTRETRIEVE)) {
+      throw cta::exception::UserError("--justarchive and --justretrieve are mutually exclusive");
+   }
+   if(has_flag(OptionBoolean::SHOW_LOG_ENTRIES) && has_flag(OptionBoolean::SUMMARY)) {
+      throw cta::exception::UserError("--log and --summary are mutually exclusive");
+   }
+
 #if 0
    m_scheduler.listQueueItems(m_cliIdentity.username, "failed queue", m_lc);
    auto archiveJobFailedList = m_scheduler.getNextArchiveJobsFailedBatch(10,m_lc);
@@ -1048,16 +1055,6 @@ void RequestMessage::processFailedRequest_Ls(const cta::admin::AdminCmd &admincm
    cmdlineOutput << "Failed retrieve jobs: " << retrieveJobFailedList.size() << std::endl;
 #endif
 
-   // header
-   std::vector<std::vector<std::string>> responseTable;
-   std::vector<std::string> header = {
-     "request type","failed jobs","total size (bytes)"
-   };
-#if 0
-   if(has_flag(OptionBoolean::SHOW_HEADER)) responseTable.push_back(header);
-#endif
-   responseTable.push_back(header);
-
    // summary
 
 #if 0
@@ -1070,9 +1067,14 @@ void RequestMessage::processFailedRequest_Ls(const cta::admin::AdminCmd &admincm
    responseTable.push_back({ "retrieve", std::to_string(retrieve_summary.candidateFiles), std::to_string(retrieve_summary.candidateBytes) });
 #endif
 
-   cmdlineOutput << formatResponse(responseTable);
-
    response.set_message_txt(cmdlineOutput.str());
+
+   // Should the client display column headers?
+   if(has_flag(OptionBoolean::SHOW_HEADER)) {
+      response.set_show_header(has_flag(OptionBoolean::SUMMARY) ?
+         HeaderType::FAILEDREQUEST_LS_SUMMARY : HeaderType::FAILEDREQUEST_LS);
+   }
+
    response.set_type(cta::xrd::Response::RSP_SUCCESS);
 }