diff --git a/README.rst b/README.rst
index c0b7e44b3267f9f1e18d2c477c009809659555da..2845db4b02aeef99884371b631b2b17a18ffb65f 100644
--- a/README.rst
+++ b/README.rst
@@ -90,8 +90,6 @@ Comments
 * particles: initialization of multistep solvers is done with lower
   order methods, so direct convergence tests will fail.
 
-* code is only known to work with HDF5 1.8.x.
-
 * code is used mainly with Python 3.5 and later, and it is not tested at
   all with Python 2.x
 
@@ -169,8 +167,7 @@ Detailed full installation instructions:
     `FFTW_LIBDIR`, `FFTW_OPEMMP_LIBDIR` and `FFTW_MPI_LIBDIR`.
 
 4.
-    Download, compile, install HDF5 (version 1.8.x, currently available
-    at https://portal.hdfgroup.org/display/support/HDF5+1.8.20#files).
+    Download, compile, install HDF5.
     We are using parallel I/O, therefore we must use the plain C interface of HDF5:
 
     .. code:: bash
diff --git a/cpp/full_code/Gauss_field_test.cpp b/cpp/full_code/Gauss_field_test.cpp
index 569d68d64235abd97d415277040df981c1476a2a..a9c604ee46352acf85c505d05cfa7c6a72f0279c 100644
--- a/cpp/full_code/Gauss_field_test.cpp
+++ b/cpp/full_code/Gauss_field_test.cpp
@@ -90,6 +90,7 @@ int Gauss_field_test<rnumber>::read_parameters()
     this->random_seed = hdf5_tools::read_value<int>(parameter_file, "/parameters/field_random_seed");
     this->output_incompressible_field = hdf5_tools::read_value<int>(parameter_file, "/parameters/output_incompressible_field");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/NSE.cpp b/cpp/full_code/NSE.cpp
index 41a85cdb746b4bf6c9016711d35363f1dfb4a1af..7c1c058d27fda089418c343145478e530f264e3c 100644
--- a/cpp/full_code/NSE.cpp
+++ b/cpp/full_code/NSE.cpp
@@ -610,6 +610,7 @@ int NSE<rnumber>::read_parameters(void)
     this->forcing_type = hdf5_tools::read_string(parameter_file, "parameters/forcing_type");
     this->fftw_plan_rigor = hdf5_tools::read_string(parameter_file, "parameters/fftw_plan_rigor");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/NSVE.cpp b/cpp/full_code/NSVE.cpp
index 77dcb7ae97dacfe207586531cf3478caaad1a48b..9abb40fa2d6beeb96887af79641165bbebb5a2e8 100644
--- a/cpp/full_code/NSVE.cpp
+++ b/cpp/full_code/NSVE.cpp
@@ -191,6 +191,8 @@ int NSVE<rnumber>::read_parameters(void)
     snprintf(this->forcing_type, 511, "%s", tmp.c_str());
     this->fftw_plan_rigor = hdf5_tools::read_string(parameter_file, "parameters/fftw_plan_rigor");
     H5Fclose(parameter_file);
+    // the following ensures the file is free after exiting this method
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/NSVE_Stokes_particles.cpp b/cpp/full_code/NSVE_Stokes_particles.cpp
index c77b9103ec6a78c05de9e1570b2f0879d1a6ab87..83a1a7eff29b9b02f017df3476546e5d4d37715f 100644
--- a/cpp/full_code/NSVE_Stokes_particles.cpp
+++ b/cpp/full_code/NSVE_Stokes_particles.cpp
@@ -220,6 +220,7 @@ int NSVE_Stokes_particles<rnumber>::read_parameters(void)
     this->tracers0_cutoff = hdf5_tools::read_value<double>(parameter_file, "parameters/tracers0_cutoff");
     this->drag_coefficient = hdf5_tools::read_value<double>(parameter_file, "parameters/drag_coefficient");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/NSVEcomplex_particles.cpp b/cpp/full_code/NSVEcomplex_particles.cpp
index a242cc642af5f43477d44072272ea6cd83dce26a..f42518f77c90eda1efb73a6a769c06bbd3123f75 100644
--- a/cpp/full_code/NSVEcomplex_particles.cpp
+++ b/cpp/full_code/NSVEcomplex_particles.cpp
@@ -257,6 +257,7 @@ int NSVEcomplex_particles<rnumber>::read_parameters(void)
     this->inner_v0 = hdf5_tools::read_value<double>(parameter_file, "parameters/tracers0_inner_v0");
     this->lambda = hdf5_tools::read_value<double>(parameter_file, "parameters/tracers0_lambda");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/NSVEp_extra_sampling.cpp b/cpp/full_code/NSVEp_extra_sampling.cpp
index 7d562341d454e63f57df3bd6118bdaece317b99b..0b96e259add4a1b6eca00eecd1ee430052ea8755 100644
--- a/cpp/full_code/NSVEp_extra_sampling.cpp
+++ b/cpp/full_code/NSVEp_extra_sampling.cpp
@@ -186,6 +186,7 @@ int NSVEp_extra_sampling<rnumber>::read_parameters(void)
     this->sample_pressure_Hessian = hdf5_tools::read_value<int>(parameter_file, "parameters/sample_pressure_Hessian");
     this->sample_velocity_gradient = hdf5_tools::read_value<int>(parameter_file, "parameters/sample_velocity_gradient");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/NSVEparticles.cpp b/cpp/full_code/NSVEparticles.cpp
index 170f0046e70f251e499d603c190e549afa3fe1bf..e9bdfaf760565ba477f8634d34b98b5719143ff2 100644
--- a/cpp/full_code/NSVEparticles.cpp
+++ b/cpp/full_code/NSVEparticles.cpp
@@ -275,6 +275,7 @@ int NSVEparticles<rnumber>::read_parameters(void)
     this->tracers0_smoothness = hdf5_tools::read_value<int>(parameter_file, "parameters/tracers0_smoothness");
     this->sample_acceleration = hdf5_tools::read_value<int>(parameter_file, "parameters/sample_acceleration");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/code_base.cpp b/cpp/full_code/code_base.cpp
index 2870d96c5742c4d6ecf30182a9d68e5fc87c45bd..1015aed91151bbcc94b5516a30a60ff6cf96f516 100644
--- a/cpp/full_code/code_base.cpp
+++ b/cpp/full_code/code_base.cpp
@@ -75,6 +75,7 @@ int code_base::read_parameters(void)
     this->nz = hdf5_tools::read_value<int>(parameter_file, "parameters/nz");
     this->dealias_type = hdf5_tools::read_value<int>(parameter_file, "parameters/dealias_type");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/code_base.hpp b/cpp/full_code/code_base.hpp
index bd9c30e1de9141242e52b31f31bc85552323e6ae..d42a7f99f10f5f71a6131e8d8bb72192315623e5 100644
--- a/cpp/full_code/code_base.hpp
+++ b/cpp/full_code/code_base.hpp
@@ -108,6 +108,12 @@ class code_base
             return EXIT_SUCCESS;
         }
 
+        /** Reads parameters
+         * \warning This method should ensure the parameter file is closed by
+         * all MPI processes when finished.
+         * One solution is to open the file in sequential mode, read-only, and
+         * then call `MPI_Barrier`.
+         */
         virtual int read_parameters(void);
         virtual int initialize(void) = 0;
         virtual int main_loop(void) = 0;
diff --git a/cpp/full_code/dealias_test.cpp b/cpp/full_code/dealias_test.cpp
index 49ffca2ad680ff27cbf4cd3bc7a63d9a6ff85115..e3afa2ac17fe66b79b4354310203e700c9601cf7 100644
--- a/cpp/full_code/dealias_test.cpp
+++ b/cpp/full_code/dealias_test.cpp
@@ -95,6 +95,7 @@ int dealias_test<rnumber>::read_parameters()
     this->spectrum_small_scale_const = hdf5_tools::read_value<double>(parameter_file, "parameters/spectrum_small_scale_const");
     this->random_seed = hdf5_tools::read_value<int>(parameter_file, "/parameters/field_random_seed");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/direct_numerical_simulation.cpp b/cpp/full_code/direct_numerical_simulation.cpp
index c686f81d25fcf400d2abc7c605671f5078c9da50..a12a79f8c7016d5c344134e054a61f6d509d5e3c 100644
--- a/cpp/full_code/direct_numerical_simulation.cpp
+++ b/cpp/full_code/direct_numerical_simulation.cpp
@@ -162,5 +162,6 @@ int direct_numerical_simulation::read_parameters(void)
     this->niter_stat = hdf5_tools::read_value<int>(parameter_file, "parameters/niter_stat");
     this->niter_todo = hdf5_tools::read_value<int>(parameter_file, "parameters/niter_todo");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
diff --git a/cpp/full_code/field_output_test.cpp b/cpp/full_code/field_output_test.cpp
index 0a3c8d6c9a7db585ff6160037bbb5c328bf72e89..89c2883a7cc48d84755004a6ba8b2a486b09dcde 100644
--- a/cpp/full_code/field_output_test.cpp
+++ b/cpp/full_code/field_output_test.cpp
@@ -50,6 +50,7 @@ int field_output_test<rnumber>::read_parameters()
 {
     TIMEZONE("field_output_test::read_parameters");
     this->test::read_parameters();
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/field_test.cpp b/cpp/full_code/field_test.cpp
index a801af1ef75975667169c89b12cba6f88f6db27b..9b4c44605584efef0033c4930a7f48f831eb9603 100644
--- a/cpp/full_code/field_test.cpp
+++ b/cpp/full_code/field_test.cpp
@@ -58,6 +58,7 @@ int field_test<rnumber>::read_parameters()
             H5P_DEFAULT);
     this->filter_length = hdf5_tools::read_value<double>(parameter_file, "/parameters/filter_length");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/filter_test.cpp b/cpp/full_code/filter_test.cpp
index dcc34e11393317d7239fb37cfd3aeafbc1ccce4c..8d0ae00fd0ec0fa5c3fd2085163953d6d3303f90 100644
--- a/cpp/full_code/filter_test.cpp
+++ b/cpp/full_code/filter_test.cpp
@@ -73,6 +73,7 @@ int filter_test<rnumber>::read_parameters()
             H5P_DEFAULT);
     this->filter_length = hdf5_tools::read_value<double>(parameter_file, "/parameters/filter_length");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/kraichnan_field.cpp b/cpp/full_code/kraichnan_field.cpp
index 661ed6fd5d4c6cf7e2dd461e4c9557e83494c9e3..32502b47d17d75dc0082036db37667474b39fa43 100644
--- a/cpp/full_code/kraichnan_field.cpp
+++ b/cpp/full_code/kraichnan_field.cpp
@@ -307,6 +307,7 @@ int kraichnan_field<rnumber>::read_parameters(void)
     this->output_velocity = hdf5_tools::read_value<int>(parameter_file, "parameters/output_velocity");
     this->max_velocity_estimate = hdf5_tools::read_value<double>(parameter_file, "parameters/max_velocity_estimate");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/native_binary_to_hdf5.cpp b/cpp/full_code/native_binary_to_hdf5.cpp
index 1c32615c0914334e8f5126cbd7ea00f8ea8723e8..a1a3277c0a0235ca97751accf55af2211eea25c2 100644
--- a/cpp/full_code/native_binary_to_hdf5.cpp
+++ b/cpp/full_code/native_binary_to_hdf5.cpp
@@ -91,6 +91,7 @@ int native_binary_to_hdf5<rnumber>::read_parameters(void)
             parameter_file,
             "/native_binary_to_hdf5/iteration_list");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/phase_shift_test.cpp b/cpp/full_code/phase_shift_test.cpp
index ca5aa4716873669996584ddaf6ca42e84acbab44..7e6c2ad402ca3becf99c497eceefd511ae61f113 100644
--- a/cpp/full_code/phase_shift_test.cpp
+++ b/cpp/full_code/phase_shift_test.cpp
@@ -51,6 +51,7 @@ int phase_shift_test<rnumber>::read_parameters()
 {
     TIMEZONE("phase_shift_test::read_parameters");
     this->test::read_parameters();
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/postprocess.cpp b/cpp/full_code/postprocess.cpp
index 2cfa5487cb1f55290542700f8d329928ef348bb6..0f80890c144ba6a64ffcfbb72e9b24ede476aea2 100644
--- a/cpp/full_code/postprocess.cpp
+++ b/cpp/full_code/postprocess.cpp
@@ -74,6 +74,7 @@ int postprocess::read_parameters()
     std::string tmp = hdf5_tools::read_string(parameter_file, "parameters/forcing_type");
     snprintf(this->forcing_type, 511, "%s", tmp.c_str());
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/static_field.cpp b/cpp/full_code/static_field.cpp
index 48396bc0600a3fc57c77d0a833b5906c03566a71..25760cf322debb4bb2438bb5242ef8fb5c01b96e 100644
--- a/cpp/full_code/static_field.cpp
+++ b/cpp/full_code/static_field.cpp
@@ -237,6 +237,7 @@ int static_field<rnumber>::read_parameters(void)
     this->tracers0_neighbours = hdf5_tools::read_value<int>(parameter_file, "parameters/tracers0_neighbours");
     this->tracers0_smoothness = hdf5_tools::read_value<int>(parameter_file, "parameters/tracers0_smoothness");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/symmetrize_test.cpp b/cpp/full_code/symmetrize_test.cpp
index 6c3880e8049c44f6b6dee3b9365bc4cab8b0e3f9..da2bef880c13dd76221477e2088dafdff6453892 100644
--- a/cpp/full_code/symmetrize_test.cpp
+++ b/cpp/full_code/symmetrize_test.cpp
@@ -58,6 +58,7 @@ int symmetrize_test<rnumber>::read_parameters()
             parameter_file, "/parameters/random_seed");
     this->fftw_plan_rigor = hdf5_tools::read_string(parameter_file, "parameters/fftw_plan_rigor");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/test_interpolation.cpp b/cpp/full_code/test_interpolation.cpp
index 2bbb1f6e54f63f3a135cb2f9dcd95121164da2ec..7325b894bac280bcf384da46a1734a52845d9727 100644
--- a/cpp/full_code/test_interpolation.cpp
+++ b/cpp/full_code/test_interpolation.cpp
@@ -44,6 +44,7 @@ int test_interpolation<rnumber>::read_parameters(void)
     this->tracers0_smoothness = hdf5_tools::read_value<int>(
             parameter_file, "/parameters/tracers0_smoothness");
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/test_tracer_set.cpp b/cpp/full_code/test_tracer_set.cpp
index df77941128a71412e2b87dce287a4cf94beca4aa..d457a090b06723c08ffc523fd483f47471de629d 100644
--- a/cpp/full_code/test_tracer_set.cpp
+++ b/cpp/full_code/test_tracer_set.cpp
@@ -55,6 +55,7 @@ int test_tracer_set<rnumber>::read_parameters()
 {
     TIMEZONE("test_tracer_set::read_parameters");
     this->test::read_parameters();
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/write_filtered_test.cpp b/cpp/full_code/write_filtered_test.cpp
index dabd7037e20ccd4e01d440f3966ea060fa7bf511..ead8916e26d0b3b3c0be3e3e98985ca6dfc237b0 100644
--- a/cpp/full_code/write_filtered_test.cpp
+++ b/cpp/full_code/write_filtered_test.cpp
@@ -57,6 +57,7 @@ int write_filtered_test<rnumber>::read_parameters()
             H5F_ACC_RDONLY,
             H5P_DEFAULT);
     H5Fclose(parameter_file);
+    MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/hdf5_tools.cpp b/cpp/hdf5_tools.cpp
index 57545fc75a3467865a01a8511ae19afad6604e50..920db174b8e665ec8e9c1101fd98b6d15ff8c9c2 100644
--- a/cpp/hdf5_tools.cpp
+++ b/cpp/hdf5_tools.cpp
@@ -145,12 +145,24 @@ int hdf5_tools::grow_file_datasets(
 
     hid_t group;
     group = H5Gopen(stat_file, group_name.c_str(), H5P_DEFAULT);
-    H5Ovisit(
+    // in the following there's ugly code because of the HDF group
+    // see https://portal.hdfgroup.org/display/HDF5/H5O_VISIT (valid link on 2021-12-12)
+#if H5_VERSION_GE(1, 12, 0) // https://portal.hdfgroup.org/display/HDF5/H5_VERSION_GE
+        H5Ovisit(
+            group,
+            H5_INDEX_NAME,
+            H5_ITER_NATIVE,
+            grow_dataset_visitor,
+            &tincrement,
+            H5O_INFO_ALL);
+#else
+        H5Ovisit(
             group,
             H5_INDEX_NAME,
             H5_ITER_NATIVE,
             grow_dataset_visitor,
             &tincrement);
+#endif//H5_VERSION_GE
     H5Gclose(group);
     return file_problems;
 }
@@ -166,12 +178,22 @@ int hdf5_tools::require_size_file_datasets(
 
     hid_t group;
     group = H5Gopen(stat_file, group_name.c_str(), H5P_DEFAULT);
+#if H5_VERSION_GE(1, 12, 0)
+    H5Ovisit(
+            group,
+            H5_INDEX_NAME,
+            H5_ITER_NATIVE,
+            require_size_dataset_visitor,
+            &tsize,
+            H5O_INFO_ALL);
+#else
     H5Ovisit(
             group,
             H5_INDEX_NAME,
             H5_ITER_NATIVE,
             require_size_dataset_visitor,
             &tsize);
+#endif//H5_VERSION_GE
     H5Gclose(group);
     return file_problems;
 }