diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
index b2a14692578501d8aa02aafa234abc3f9e7aa484..bf722cfbae3c1358b5682c0e2b5716bc34c49cbf 100644
--- a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
+++ b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
@@ -831,11 +831,18 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
 
 
         // Statistics
+        Info<< nl << "Processor " << proci;
 
-        Info<< endl
-            << "Processor " << proci << nl
-            << "    Number of cells = " << procMesh.nCells()
-            << endl;
+        if (procMesh.nCells())
+        {
+            Info<< nl << "    ";
+        }
+        else
+        {
+            Info<< ": ";
+        }
+
+        Info<< "Number of cells = " << procMesh.nCells() << nl;
 
         maxProcCells = max(maxProcCells, procMesh.nCells());
 
@@ -865,9 +872,12 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
             }
         }
 
-        Info<< "    Number of processor patches = " << nProcPatches << nl
-            << "    Number of processor faces = " << nProcFaces << nl
-            << "    Number of boundary faces = " << nBoundaryFaces << endl;
+        if (procMesh.nCells() && (nBoundaryFaces || nProcFaces))
+        {
+            Info<< "    Number of processor patches = " << nProcPatches << nl
+                << "    Number of processor faces = " << nProcFaces << nl
+                << "    Number of boundary faces = " << nBoundaryFaces << nl;
+        }
 
         totProcFaces += nProcFaces;
         totProcPatches += nProcPatches;
diff --git a/src/OpenFOAM/meshes/polyMesh/polyMesh.C b/src/OpenFOAM/meshes/polyMesh/polyMesh.C
index 6c44d9e8d1b42269e9ba9eb8b302404d46388ed6..de8d164ef75e2047a484746b4c9e908a5e7fc8d7 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyMesh.C
@@ -325,15 +325,21 @@ Foam::polyMesh::polyMesh(const IOobject& io)
     boundary_.calcGeometry();
 
     // Warn if global empty mesh
-    if (returnReduce(nPoints(), sumOp<label>()) == 0)
+    if (returnReduce(boundary_.empty(), orOp<bool>()))
     {
         WarningInFunction
-            << "no points in mesh" << endl;
-    }
-    if (returnReduce(nCells(), sumOp<label>()) == 0)
-    {
-        WarningInFunction
-            << "no cells in mesh" << endl;
+            << "mesh missing boundary on one or more domains" << endl;
+
+        if (returnReduce(nPoints(), sumOp<label>()) == 0)
+        {
+            WarningInFunction
+                << "no points in mesh" << endl;
+        }
+        if (returnReduce(nCells(), sumOp<label>()) == 0)
+        {
+            WarningInFunction
+                << "no cells in mesh" << endl;
+        }
     }
 
     // Initialise demand-driven data
diff --git a/src/dynamicMesh/polyMeshAdder/faceCoupleInfo.C b/src/dynamicMesh/polyMeshAdder/faceCoupleInfo.C
index e1c8a08e64d28814dc4273c964bbf3edb0e57685..3c3edde47d70c5667dc7d0de676ef669ad9ee965 100644
--- a/src/dynamicMesh/polyMeshAdder/faceCoupleInfo.C
+++ b/src/dynamicMesh/polyMeshAdder/faceCoupleInfo.C
@@ -886,6 +886,15 @@ void Foam::faceCoupleInfo::findPerfectMatchingFaces
     labelList& mesh1Faces
 )
 {
+    // Quick check: skip face matching if either mesh has no faces
+    if (!mesh0.nFaces() || !mesh1.nFaces())
+    {
+        mesh0Faces.clear();
+        mesh1Faces.clear();
+
+        return;
+    }
+
     // Face centres of external faces (without invoking
     // mesh.faceCentres since mesh might have been clearedOut)