diff --git a/NumLib/ODESolver/NonlinearSolver.cpp b/NumLib/ODESolver/NonlinearSolver.cpp
index f689ddba6a3082ec39c163628cbdb2ca55f68712..62ea46f0aa8a3f0f5da2b6168f813b56bcbcc952 100644
--- a/NumLib/ODESolver/NonlinearSolver.cpp
+++ b/NumLib/ODESolver/NonlinearSolver.cpp
@@ -126,7 +126,7 @@ void NonlinearSolver<NonlinearSolverTag::Picard>::
 NonlinearSolverStatus NonlinearSolver<NonlinearSolverTag::Picard>::solve(
     std::vector<GlobalVector*>& x,
     std::vector<GlobalVector*> const& x_prev,
-    std::function<void(int, std::vector<GlobalVector*> const&)> const&
+    std::function<void(int, bool, std::vector<GlobalVector*> const&)> const&
         postIterationCallback,
     int const process_id)
 {
@@ -212,7 +212,7 @@ NonlinearSolverStatus NonlinearSolver<NonlinearSolverTag::Picard>::solve(
         {
             if (postIterationCallback)
             {
-                postIterationCallback(iteration, x_new);
+                postIterationCallback(iteration, error_norms_met, x_new);
             }
 
             switch (sys.postIteration(x_new_process))
@@ -330,7 +330,7 @@ void NonlinearSolver<NonlinearSolverTag::Newton>::
 NonlinearSolverStatus NonlinearSolver<NonlinearSolverTag::Newton>::solve(
     std::vector<GlobalVector*>& x,
     std::vector<GlobalVector*> const& x_prev,
-    std::function<void(int, std::vector<GlobalVector*> const&)> const&
+    std::function<void(int, bool, std::vector<GlobalVector*> const&)> const&
         postIterationCallback,
     int const process_id)
 {
@@ -453,7 +453,7 @@ NonlinearSolverStatus NonlinearSolver<NonlinearSolverTag::Newton>::solve(
 
             if (postIterationCallback)
             {
-                postIterationCallback(iteration, x_new);
+                postIterationCallback(iteration, error_norms_met, x_new);
             }
 
             switch (sys.postIteration(*x_new[process_id]))
diff --git a/NumLib/ODESolver/NonlinearSolver.h b/NumLib/ODESolver/NonlinearSolver.h
index f4fede727ffd0908efd18c2f6d9ebf6d83327377..494085557f220117296d4be75ff54c5c2310a439 100644
--- a/NumLib/ODESolver/NonlinearSolver.h
+++ b/NumLib/ODESolver/NonlinearSolver.h
@@ -53,7 +53,7 @@ public:
     virtual NonlinearSolverStatus solve(
         std::vector<GlobalVector*>& x,
         std::vector<GlobalVector*> const& x_prev,
-        std::function<void(int, std::vector<GlobalVector*> const&)> const&
+        std::function<void(int, bool, std::vector<GlobalVector*> const&)> const&
             postIterationCallback,
         int const process_id) = 0;
 
@@ -118,7 +118,7 @@ public:
     NonlinearSolverStatus solve(
         std::vector<GlobalVector*>& x,
         std::vector<GlobalVector*> const& x_prev,
-        std::function<void(int, std::vector<GlobalVector*> const&)> const&
+        std::function<void(int, bool, std::vector<GlobalVector*> const&)> const&
             postIterationCallback,
         int const process_id) override;
 
@@ -202,7 +202,7 @@ public:
     NonlinearSolverStatus solve(
         std::vector<GlobalVector*>& x,
         std::vector<GlobalVector*> const& x_prev,
-        std::function<void(int, std::vector<GlobalVector*> const&)> const&
+        std::function<void(int, bool, std::vector<GlobalVector*> const&)> const&
             postIterationCallback,
         int const process_id) override;
 
diff --git a/NumLib/ODESolver/PETScNonlinearSolver.cpp b/NumLib/ODESolver/PETScNonlinearSolver.cpp
index 73691919bfbd6070a5a2fcf136362bd8e78959c5..01f99861805bd92dff499c94d4d81872ac2db99f 100644
--- a/NumLib/ODESolver/PETScNonlinearSolver.cpp
+++ b/NumLib/ODESolver/PETScNonlinearSolver.cpp
@@ -149,7 +149,7 @@ NonlinearSolverStatus PETScNonlinearSolver::solve(
     std::vector<GlobalVector*>& x,
     std::vector<GlobalVector*> const& x_prev,
     std::function<void(
-        int,
+        int, bool,
         std::vector<GlobalVector*> const&)> const& /*postIterationCallback*/,
     int const process_id)
 {
diff --git a/NumLib/ODESolver/PETScNonlinearSolver.h b/NumLib/ODESolver/PETScNonlinearSolver.h
index b216aa41cf16d40251dea2ab0ba31171ad9f052f..0a682ac9b84f9aed3ba0178bc2d41f80f96a4c0e 100644
--- a/NumLib/ODESolver/PETScNonlinearSolver.h
+++ b/NumLib/ODESolver/PETScNonlinearSolver.h
@@ -51,7 +51,7 @@ public:
     NonlinearSolverStatus solve(
         std::vector<GlobalVector*>& x,
         std::vector<GlobalVector*> const& x_prev,
-        std::function<void(int, std::vector<GlobalVector*> const&)> const&
+        std::function<void(int, bool, std::vector<GlobalVector*> const&)> const&
             postIterationCallback,
         int const process_id) override;
 
diff --git a/ProcessLib/Output/Output.cpp b/ProcessLib/Output/Output.cpp
index 78455666fafbbfbcc5d58bc2b864287d24d4643f..84cf4df4d9a6fb9c0a7a7b69e1a85b91b05ff415 100644
--- a/ProcessLib/Output/Output.cpp
+++ b/ProcessLib/Output/Output.cpp
@@ -176,6 +176,7 @@ void Output::doNotProjectFromBulkMeshToSubmeshes(
 
 void Output::outputMeshes(
     const int timestep, const double t, const int iteration,
+    bool const converged,
     std::vector<std::reference_wrapper<const MeshLib::Mesh>> const& meshes)
     const
 {
@@ -208,7 +209,7 @@ void Output::outputMeshes(
             }
         }
     }
-    _output_format->outputMeshes(timestep, t, iteration, meshes,
+    _output_format->outputMeshes(timestep, t, iteration, converged, meshes,
                                  _output_data_specification.output_variables);
 }
 
@@ -291,6 +292,7 @@ void Output::doOutputAlways(Process const& process,
                             int const timestep,
                             const NumLib::Time& t,
                             int const iteration,
+                            bool const converged,
                             std::vector<GlobalVector*> const& xs) const
 {
     BaseLib::RunTime time_output;
@@ -327,7 +329,7 @@ void Output::doOutputAlways(Process const& process,
         }
     }
 
-    outputMeshes(timestep, t(), iteration, std::move(output_meshes));
+    outputMeshes(timestep, t(), iteration, converged, std::move(output_meshes));
 
     INFO("[time] Output of timestep {:d} took {:g} s.", timestep,
          time_output.elapsed());
@@ -338,11 +340,13 @@ void Output::doOutput(Process const& process,
                       int const timestep,
                       const NumLib::Time& t,
                       int const iteration,
+                      bool const converged,
                       std::vector<GlobalVector*> const& xs) const
 {
     if (isOutputStep(timestep, t))
     {
-        doOutputAlways(process, process_id, timestep, t, iteration, xs);
+        doOutputAlways(process, process_id, timestep, t, iteration, converged,
+                       xs);
     }
 #ifdef OGS_USE_INSITU
     // Note: last time step may be output twice: here and in
@@ -357,11 +361,13 @@ void Output::doOutputLastTimestep(Process const& process,
                                   int const timestep,
                                   const NumLib::Time& t,
                                   int const iteration,
+                                  bool const converged,
                                   std::vector<GlobalVector*> const& xs) const
 {
     if (!isOutputStep(timestep, t))
     {
-        doOutputAlways(process, process_id, timestep, t, iteration, xs);
+        doOutputAlways(process, process_id, timestep, t, iteration, converged,
+                       xs);
     }
 #ifdef OGS_USE_INSITU
     InSituLib::CoProcess(process.getMesh(), t, timestep, true,
@@ -371,7 +377,7 @@ void Output::doOutputLastTimestep(Process const& process,
 
 void Output::doOutputNonlinearIteration(
     Process const& process, const int process_id, int const timestep,
-    const NumLib::Time& t, int const iteration,
+    const NumLib::Time& t, int const iteration, bool const converged,
     std::vector<GlobalVector*> const& xs) const
 {
     if (!_output_nonlinear_iteration_results)
@@ -423,8 +429,10 @@ bool Output::isOutputStep(int const timestep, NumLib::Time const& t) const
 std::vector<std::string> Output::getFileNamesForOutput() const
 {
     auto construct_filename = ranges::views::transform(
-        [&](auto const& output_name)
-        { return _output_format->constructFilename(output_name, 0, 0, 0); });
+        [&](auto const& output_name) {
+            return _output_format->constructFilename(output_name, 0, 0, 0,
+                                                     true);
+        });
 
     return _mesh_names_for_output | construct_filename |
            ranges::to<std::vector>;
diff --git a/ProcessLib/Output/Output.h b/ProcessLib/Output/Output.h
index 1fd79d73c552f6285c9366e64464415ff29f1a13..3dd872250b252a81fd58319550b6889d4d90e6a6 100644
--- a/ProcessLib/Output/Output.h
+++ b/ProcessLib/Output/Output.h
@@ -61,7 +61,7 @@ public:
     //! the given \c timestep.
     void doOutput(Process const& process, const int process_id,
                   int const timestep, const NumLib::Time& t,
-                  int const iteration,
+                  int const iteration, bool const converged,
                   std::vector<GlobalVector*> const& xs) const;
 
     //! Writes output for the given \c process if it has not been written yet.
@@ -69,7 +69,7 @@ public:
     //! order to make sure that its results are written.
     void doOutputLastTimestep(Process const& process, const int process_id,
                               int const timestep, const NumLib::Time& t,
-                              int const iteration,
+                              int const iteration, bool const converged,
                               std::vector<GlobalVector*> const& xs) const;
 
     //! Writes output for the given \c process.
@@ -77,7 +77,7 @@ public:
     //! It is intended to write output in error handling routines.
     void doOutputAlways(Process const& process, const int process_id,
                         int const timestep, const NumLib::Time& t,
-                        int const iteration,
+                        int const iteration, bool const converged,
                         std::vector<GlobalVector*> const& xs) const;
 
     //! Writes output for the given \c process.
@@ -85,6 +85,7 @@ public:
     void doOutputNonlinearIteration(Process const& process,
                                     const int process_id, int const timestep,
                                     const NumLib::Time& t, const int iteration,
+                                    bool const converged,
                                     std::vector<GlobalVector*> const& xs) const;
 
     //! Tells if output will be written at the specified timestep/time.
@@ -107,6 +108,7 @@ private:
 
     void outputMeshes(
         int const timestep, const double t, int const iteration,
+        bool const converged,
         std::vector<std::reference_wrapper<const MeshLib::Mesh>> const& meshes)
         const;
 
diff --git a/ProcessLib/Output/OutputFormat.cpp b/ProcessLib/Output/OutputFormat.cpp
index 63c99108ae9de22aaabed9bdb0348342d95f1bd2..30ffe445d2f30a66b182043c8d88b9bdf0eb40b7 100644
--- a/ProcessLib/Output/OutputFormat.cpp
+++ b/ProcessLib/Output/OutputFormat.cpp
@@ -56,10 +56,11 @@ void outputMeshVtk(std::string const& file_name, MeshLib::Mesh const& mesh,
 
 void outputMeshVtk(OutputVTKFormat const& output_file,
                    MeshLib::IO::PVDFile& pvd_file, MeshLib::Mesh const& mesh,
-                   double const t, int const timestep, int const iteration)
+                   double const t, int const timestep, int const iteration,
+                   bool const converged)
 {
-    auto const name =
-        output_file.constructFilename(mesh.getName(), timestep, t, iteration);
+    auto const name = output_file.constructFilename(mesh.getName(), timestep, t,
+                                                    iteration, converged);
     pvd_file.addVTUFile(name, t);
 
     auto const path = BaseLib::joinPaths(output_file.directory, name);
@@ -114,13 +115,14 @@ std::string OutputXDMFHDF5Format::constructFilename(
 void OutputXDMFHDF5Format::outputMeshXdmf(
     std::set<std::string> const& output_variables,
     std::vector<std::reference_wrapper<const MeshLib::Mesh>> const& meshes,
-    int const timestep, double const t, int const iteration) const
+    int const timestep, double const t, int const iteration,
+    bool const converged) const
 {
     // \TODO The XdmfOutput will create on construction the XdmfHdfWriter
     if (!mesh_xdmf_hdf_writer)
     {
         auto name = constructFilename(meshes[0].get().getName(), timestep, t,
-                                      iteration);
+                                      iteration, converged);
         std::filesystem::path path(BaseLib::joinPaths(directory, name));
         mesh_xdmf_hdf_writer = std::make_unique<MeshLib::IO::XdmfHdfWriter>(
             meshes, path, timestep, t, output_variables, compression, n_files,
@@ -134,13 +136,14 @@ void OutputXDMFHDF5Format::outputMeshXdmf(
 
 void OutputVTKFormat::outputMeshes(
     const int timestep, const double t, const int iteration,
+    bool const converged,
     std::vector<std::reference_wrapper<const MeshLib::Mesh>> const& meshes,
     [[maybe_unused]] std::set<std::string> const& output_variables) const
 {
     for (auto const& mesh : meshes)
     {
         auto& pvd_file = findOrCreatePVDFile(mesh.get().getName());
-        outputMeshVtk(*this, pvd_file, mesh, t, timestep, iteration);
+        outputMeshVtk(*this, pvd_file, mesh, t, timestep, iteration, converged);
     }
 }
 }  // namespace ProcessLib
diff --git a/ProcessLib/Output/OutputFormat.h b/ProcessLib/Output/OutputFormat.h
index d9db48eab1ebe8df9dd7ee59afaa5a66727dc85f..7068450d8fc96a88fcceb77c0c95b84e3ede5afb 100644
--- a/ProcessLib/Output/OutputFormat.h
+++ b/ProcessLib/Output/OutputFormat.h
@@ -39,6 +39,7 @@ struct OutputFormat
 
     virtual void outputMeshes(
         const int timestep, const double t, const int iteration,
+        bool const converged,
         std::vector<std::reference_wrapper<const MeshLib::Mesh>> const& meshes,
         std::set<std::string> const& output_variables) const = 0;
     virtual std::string constructFilename(std::string const& mesh_name,
@@ -69,6 +70,7 @@ struct OutputVTKFormat final : public OutputFormat
 
     void outputMeshes(
         const int timestep, const double t, const int iteration,
+        bool const converged,
         std::vector<std::reference_wrapper<const MeshLib::Mesh>> const& meshes,
         std::set<std::string> const& output_variables) const override;
 
@@ -107,10 +109,12 @@ struct OutputXDMFHDF5Format final : public OutputFormat
 
     void outputMeshes(
         const int timestep, const double t, const int iteration,
+        bool const converged,
         std::vector<std::reference_wrapper<const MeshLib::Mesh>> const& meshes,
         std::set<std::string> const& output_variables) const override
     {
-        outputMeshXdmf(output_variables, meshes, timestep, t, iteration);
+        outputMeshXdmf(output_variables, meshes, timestep, t, iteration,
+                       converged);
     }
 
     std::string constructFilename(std::string const& mesh_name,
@@ -127,7 +131,8 @@ struct OutputXDMFHDF5Format final : public OutputFormat
     void outputMeshXdmf(
         std::set<std::string> const& output_variables,
         std::vector<std::reference_wrapper<const MeshLib::Mesh>> const& meshes,
-        int const timestep, double const t, int const iteration) const;
+        int const timestep, double const t, int const iteration,
+        bool const converged) const;
 };
 
 void outputMeshVtk(std::string const& file_name, MeshLib::Mesh const& mesh,
diff --git a/ProcessLib/TimeLoop.cpp b/ProcessLib/TimeLoop.cpp
index 06d6e74c96cd30536c7305514211f0bec6a2094b..7bb55d5fdb289efe57d543f9c73568c665370b25 100644
--- a/ProcessLib/TimeLoop.cpp
+++ b/ProcessLib/TimeLoop.cpp
@@ -241,7 +241,8 @@ NumLib::NonlinearSolverStatus solveOneTimeStepOneProcess(
     time_disc.nextTimestep(t, delta_t);
 
     auto const post_iteration_callback =
-        [&](int iteration, std::vector<GlobalVector*> const& x)
+        [&](int const iteration, bool const converged,
+            std::vector<GlobalVector*> const& x)
     {
         // Note: We don't call the postNonLinearSolver(), preOutput(),
         // computeSecondaryVariable() and postTimestep() hooks here. This might
@@ -249,7 +250,8 @@ NumLib::NonlinearSolverStatus solveOneTimeStepOneProcess(
         for (auto const& output : outputs)
         {
             output.doOutputNonlinearIteration(process, process_id, timestep,
-                                              NumLib::Time(t), iteration, x);
+                                              NumLib::Time(t), iteration,
+                                              converged, x);
         }
     };
 
@@ -667,6 +669,7 @@ NumLib::NonlinearSolverStatus TimeLoop::solveUncoupledEquationSystems(
                     output.doOutputAlways(
                         process_data->process, process_id, timestep_id, t,
                         process_data->nonlinear_solver_status.number_iterations,
+                        process_data->nonlinear_solver_status.error_norms_met,
                         _process_solutions);
                 }
                 OGS_FATAL(timestepper_cannot_reduce_dt.data());
@@ -726,6 +729,7 @@ void TimeLoop::outputSolutions(unsigned timestep, const double t,
             (output_object.*output_class_member)(
                 pcs, process_id, timestep, NumLib::Time(t),
                 process_data->nonlinear_solver_status.number_iterations,
+                process_data->nonlinear_solver_status.error_norms_met,
                 _process_solutions);
         }
     }