diff --git a/Filters/Core/Testing/Cxx/CMakeLists.txt b/Filters/Core/Testing/Cxx/CMakeLists.txt
index 0196a260ac74589c9993db32f0b1916850ad8a61..ddc1f71acad95f9d8b0faaf40159aadd9c84c5e4 100644
--- a/Filters/Core/Testing/Cxx/CMakeLists.txt
+++ b/Filters/Core/Testing/Cxx/CMakeLists.txt
@@ -109,4 +109,13 @@ set(all_tests
   ${no_vtkm_tests}
   )
 
+if (TARGET VTK::ParallelMPI)
+  set(vtkFiltersCoreCxxTests-MPI_NUMPROCS 2)
+  vtk_add_test_mpi(vtkFiltersCoreCxxTests-MPI mpi_test
+    TestAppendFilterDistributed.cxx,NO_VALID
+  )
+
+  vtk_test_cxx_executable(vtkFiltersCoreCxxTests-MPI mpi_test)
+endif()
+
 vtk_test_cxx_executable(vtkFiltersCoreCxxTests all_tests)
diff --git a/Filters/Core/Testing/Cxx/TestAppendFilterDistributed.cxx b/Filters/Core/Testing/Cxx/TestAppendFilterDistributed.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..572c441e4453895088a66ac73919a038a97f12dc
--- /dev/null
+++ b/Filters/Core/Testing/Cxx/TestAppendFilterDistributed.cxx
@@ -0,0 +1,61 @@
+// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+// SPDX-License-Identifier: BSD-3-Clause
+
+#include "vtkImageData.h"
+#include "vtkMPIController.h"
+#include "vtkUnstructuredGrid.h"
+
+#include <vtkAppendFilter.h>
+#include <vtkGenerateGlobalIds.h>
+#include <vtkGeometryFilter.h>
+#include <vtkLogger.h>
+#include <vtkRedistributeDataSetFilter.h>
+#include <vtkSpatioTemporalHarmonicsSource.h>
+
+int TestAppendFilterDistributed(int argc, char* argv[])
+{
+  // Initialize MPI Controller
+  vtkNew<vtkMPIController> controller;
+  controller->Initialize(&argc, &argv);
+  vtkMultiProcessController::SetGlobalController(controller);
+
+  vtkNew<vtkSpatioTemporalHarmonicsSource> source;
+  source->Update();
+
+  vtkNew<vtkGenerateGlobalIds> globalIds;
+  globalIds->SetInputData(source->GetOutput());
+  globalIds->SetTolerance(0);
+  globalIds->Update();
+
+  vtkNew<vtkRedistributeDataSetFilter> redistribute;
+  redistribute->SetInputData(globalIds->GetOutput());
+  redistribute->Update();
+
+  // This filter is only here to test cell's faces and points validity, it will crash if invalid.
+  vtkNew<vtkGeometryFilter> geometry;
+  geometry->SetInputData(redistribute->GetOutput());
+  geometry->Update();
+
+  vtkSmartPointer<vtkUnstructuredGrid> grid =
+    vtkUnstructuredGrid::SafeDownCast(redistribute->GetOutput());
+
+  if (grid->GetNumberOfCells() != 8000)
+  {
+    std::cerr << "Incorrect number of cells. Expected 8000 got " << grid->GetNumberOfCells()
+              << std::endl;
+    controller->Finalize();
+    return EXIT_FAILURE;
+  }
+
+  if (grid->GetNumberOfPoints() != 4851)
+  {
+    std::cerr << "Incorrect number of points. Expected 4851 got " << grid->GetNumberOfPoints()
+              << std::endl;
+    controller->Finalize();
+    return EXIT_FAILURE;
+  }
+
+  controller->Finalize();
+
+  return EXIT_SUCCESS;
+}
diff --git a/Filters/Core/vtk.module b/Filters/Core/vtk.module
index a9bd1e45cab98969037ed1c884a12b26aa0eb93e..f370846d70ad4a0dae8f57a7fc0bd1b4c884fe9b 100644
--- a/Filters/Core/vtk.module
+++ b/Filters/Core/vtk.module
@@ -54,3 +54,5 @@ TEST_DEPENDS
   VTK::TestingDataModel
 TEST_OPTIONAL_DEPENDS
   VTK::AcceleratorsVTKmFilters
+  VTK::mpi
+  VTK::ParallelMPI
diff --git a/Filters/Core/vtkAppendFilter.cxx b/Filters/Core/vtkAppendFilter.cxx
index 1087d921ca9170ee93e927482a341756316f64ea..f7a6c23c23939a55bc66bd865a091605e9d95699 100644
--- a/Filters/Core/vtkAppendFilter.cxx
+++ b/Filters/Core/vtkAppendFilter.cxx
@@ -302,34 +302,30 @@ int vtkAppendFilter::RequestData(vtkInformation* vtkNotUsed(request),
     {
       if (reallyMergePoints)
       {
-        if (!dataSet->HasAnyGhostPoints() ||
-          dataSet->GetGhostArray(vtkDataObject::POINT)->GetValue(ptId) == 0)
+        if (dataSetGlobalIdsArray)
         {
-          if (dataSetGlobalIdsArray)
+          vtkIdType globalId = dataSetGlobalIdsArray->GetValue(ptId);
+          auto it = addedPointsMap.find(globalId);
+          if (it == addedPointsMap.end())
           {
-            vtkIdType globalId = dataSetGlobalIdsArray->GetValue(ptId);
-            auto it = addedPointsMap.find(globalId);
-            if (it == addedPointsMap.end())
-            {
-              globalIndices[ptId + ptOffset] = newPts->GetNumberOfPoints();
-              dataSet->GetPoint(ptId, p);
-              vtkIdType newPtId = newPts->InsertNextPoint(p);
-              addedPointsMap.emplace(globalId, newPtId);
-            }
-            else
-            {
-              globalIndices[ptId + ptOffset] = it->second;
-            }
+            globalIndices[ptId + ptOffset] = newPts->GetNumberOfPoints();
+            dataSet->GetPoint(ptId, p);
+            vtkIdType newPtId = newPts->InsertNextPoint(p);
+            addedPointsMap.emplace(globalId, newPtId);
           }
           else
           {
-            vtkIdType globalPtId = 0;
-            dataSet->GetPoint(ptId, p);
-            ptInserter->InsertUniquePoint(p, globalPtId);
-            globalIndices[ptId + ptOffset] = globalPtId;
-            // The point inserter puts the point into newPts, so we don't have to do that here.
+            globalIndices[ptId + ptOffset] = it->second;
           }
         }
+        else
+        {
+          vtkIdType globalPtId = 0;
+          dataSet->GetPoint(ptId, p);
+          ptInserter->InsertUniquePoint(p, globalPtId);
+          globalIndices[ptId + ptOffset] = globalPtId;
+          // The point inserter puts the point into newPts, so we don't have to do that here.
+        }
       }
       else
       {
@@ -481,7 +477,8 @@ void vtkAppendFilter::AppendArrays(int attributesType, vtkInformationVector** in
       const auto numberOfInputTuples = inputData->GetNumberOfTuples();
       for (vtkIdType id = 0; id < numberOfInputTuples; ++id)
       {
-        if (!reallyMergePoints || !dataSet->HasAnyGhostPoints() ||
+        if (attributesType != vtkDataObject::POINT || !reallyMergePoints ||
+          !dataSet->HasAnyGhostPoints() ||
           dataSet->GetGhostArray(vtkDataObject::POINT)->GetValue(id) == 0)
         {
           if (globalIds != nullptr)