diff --git a/nomad/config.py b/nomad/config.py
index 23116806251b58d09dfcd349ea9ded696b593f67..ab87be0f89684a90bbfbf903f6fab892087acaee 100644
--- a/nomad/config.py
+++ b/nomad/config.py
@@ -239,8 +239,8 @@ normalize = NomadConfig(
     # The threshold for point equality in k-space. Unit: 1/m.
     k_space_precision=150e6,
     # The energy threshold for how much a band can be on top or below the fermi
-    # level in order to detect a gap. k_B x T at room temperature. Unit: Joule
-    band_structure_energy_tolerance=300 * 1.38064852E-23,
+    # level in order to detect a gap. Unit: Joule.
+    band_structure_energy_tolerance=1.6022e-20,  # 0.1 eV
     springer_db_path=os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         'normalizing/data/springer.msg'
diff --git a/nomad/datamodel/metainfo/public.py b/nomad/datamodel/metainfo/public.py
index d1e4292c1442ff65705dcc7d6bb02b8ee78088e8..056b16322fe756690c012c58513064001161a517 100644
--- a/nomad/datamodel/metainfo/public.py
+++ b/nomad/datamodel/metainfo/public.py
@@ -1264,10 +1264,17 @@ class section_dos(MSection):
         shape=['number_of_dos_values'],
         unit='joule',
         description='''
-        Array containing the set of discrete energy values with respect to the top of the
-        valence band for the density (electronic-energy) of states (DOS). This is the
-        total DOS, see atom_projected_dos_energies and species_projected_dos_energies for
+        Array containing the set of discrete energy values with respect to the
+        highest occupied energy level. This is the total DOS, see
+        atom_projected_dos_energies and species_projected_dos_energies for
         partial density of states.
+
+        If not available through energy_reference_highest_occupied, the highest
+        occupied energy level is detected by searching for a non-zero DOS value
+        below (or nearby) the reported energy_reference_fermi. In case the
+        highest occupied energy level cannot be detected accurately, the
+        normalized values are not reported. For calculations with multiple
+        spin-channels, the normalization is determined by the first channel.
         ''',
         a_legacy=LegacyDefinition(name='dos_energies_normalized'))
 
diff --git a/nomad/normalizing/dos.py b/nomad/normalizing/dos.py
index 10b0633e547f91a6856dda5735d3eb2d5f71e5cc..c8e8809e63ee0af58450f92e3da70066ad4f1522 100644
--- a/nomad/normalizing/dos.py
+++ b/nomad/normalizing/dos.py
@@ -47,7 +47,8 @@ class DosNormalizer(Normalizer):
                 dos_values = dos.dos_values
                 dos_energies = dos.dos_energies
                 energy_reference_fermi = scc.energy_reference_fermi
-                if dos_energies is None or dos_values is None or energy_reference_fermi is None:
+                energy_reference_highest_occupied = scc.energy_reference_highest_occupied
+                if dos_energies is None or dos_values is None or (energy_reference_fermi is None and energy_reference_highest_occupied is None):
                     continue
 
                 # Normalize DOS values to be 1/J/atom/m^3
@@ -68,75 +69,90 @@ class DosNormalizer(Normalizer):
                 dos_values_normalized = dos_values / (number_of_atoms * unit_cell_volume)
 
                 # Normalize energies so that they are normalized to HOMO.
-                i_channel = 0
-                fermi_energy = energy_reference_fermi[i_channel]
-                fermi_idx = (np.abs(dos_energies - fermi_energy)).argmin()
-                energy_threshold = config.normalize.band_structure_energy_tolerance
-                value_threshold = 1e-8  # The DOS value that is considered to be zero
-                homo_found = False
-                zero_found = False
-                energy_reference = fermi_energy
-
-                # Walk through the energies in descencing direction to see if a
-                # gap is nearby (see energy_threshold). If gap found, continue
-                # until HOMO found
-                idx = fermi_idx
-                while True:
-                    try:
-                        value = dos_values_normalized[i_channel, idx]
-                        energy_distance = fermi_energy - dos_energies[idx]
-                    except IndexError:
-                        break
-                    if energy_distance.magnitude > energy_threshold and not zero_found:
-                        break
-                    if value <= value_threshold:
-                        zero_found = True
-                    if zero_found and value > value_threshold:
-                        energy_reference = dos_energies[idx + 1]
-                        homo_found = True
-                        break
-                    idx -= 1
-                # If gap was not found in descending direction, check the
-                # ascending direction for a nearby (see energy_threshold) HOMO
-                # value
-                if not homo_found:
-                    idx = fermi_idx + 1
-                    while True:
-                        try:
-                            value = dos_values_normalized[i_channel, idx]
-                            energy_distance = dos_energies[idx] - fermi_energy
-                        except IndexError:
-                            break
-                        if energy_distance.magnitude > energy_threshold:
-                            break
-                        if value <= value_threshold:
-                            energy_reference = dos_energies[idx]
-                            break
-                        idx += 1
-
-                dos_energies_normalized = dos_energies - energy_reference
-
-                # Data for DOS fingerprint
-                dos_fingerprint = None
-                try:
-                    dos_fingerprint = DOSFingerprint().calculate(
-                        dos_energies_normalized.magnitude,
-                        dos_values_normalized,
-                        n_atoms=number_of_atoms
-                    )
-                except Exception as e:
-                    self.logger.error('could not generate dos fingerprint', exc_info=e)
+                dos_energies_normalized = None
+
+                # Primarily normalize to the HOMO level reported by the parser.
+                # The first channel is used.
+                energy_reference = None
+                if energy_reference_highest_occupied is not None:
+                    energy_reference = energy_reference_highest_occupied[0]
+                # If HOMO is not reported, search for it in the DOS values
+                else:
+                    i_channel = 0
+                    fermi_energy = energy_reference_fermi[i_channel]
+                    fermi_idx = (np.abs(dos_energies - fermi_energy)).argmin()
+                    energy_threshold = config.normalize.band_structure_energy_tolerance
+                    value_threshold = 1e-8  # The DOS value that is considered to be zero
+                    homo_found = False
+                    zero_found = False
+                    energy_reference = fermi_energy
+
+                    # First check that the closest dos energy to fermi_energy is not too
+                    # far away. If it is very far away, the normalization may be very
+                    # inaccurate and we do not report it.
+                    fermi_energy_closest = dos_energies[fermi_idx]
+                    distance = np.abs(fermi_energy_closest - fermi_energy)
+                    if distance.magnitude <= energy_threshold:
+
+                        # Walk through the energies in descencing direction to see if a
+                        # gap is nearby (see energy_threshold). If gap found, continue
+                        # until HOMO found
+                        idx = fermi_idx
+                        while True:
+                            try:
+                                value = dos_values_normalized[i_channel, idx]
+                                energy_distance = fermi_energy_closest - dos_energies[idx]
+                            except IndexError:
+                                break
+                            if energy_distance.magnitude > energy_threshold and not zero_found:
+                                break
+                            if value <= value_threshold:
+                                zero_found = True
+                            if zero_found and value > value_threshold:
+                                energy_reference = dos_energies[idx + 1]
+                                homo_found = True
+                                break
+                            idx -= 1
+                        # If gap was not found in descending direction, check the
+                        # ascending direction for a nearby (see energy_threshold) HOMO
+                        # value
+                        if not homo_found:
+                            idx = fermi_idx + 1
+                            while True:
+                                try:
+                                    value = dos_values_normalized[i_channel, idx]
+                                    energy_distance = dos_energies[idx] - fermi_energy
+                                except IndexError:
+                                    break
+                                if energy_distance.magnitude > energy_threshold:
+                                    break
+                                if value <= value_threshold:
+                                    energy_reference = dos_energies[idx]
+                                    break
+                                idx += 1
 
                 # Add quantities to NOMAD's Metainfo
                 scc_url = '/section_run/0/section_single_configuration_calculation/%d/section_dos/0' % scc.m_parent_index
                 self._backend.openContext(scc_url)
                 dos.dos_values_normalized = dos_values_normalized
-                dos.dos_energies_normalized = dos_energies_normalized
-                if dos_fingerprint is not None:
-                    sec_dos_fingerprint = dos.m_create(section_dos_fingerprint)
-                    sec_dos_fingerprint.bins = dos_fingerprint.bins
-                    sec_dos_fingerprint.indices = dos_fingerprint.indices
-                    sec_dos_fingerprint.stepsize = dos_fingerprint.stepsize
-                    sec_dos_fingerprint.grid_id = dos_fingerprint.grid_id
-                    sec_dos_fingerprint.filling_factor = dos_fingerprint.filling_factor
+
+                # Data for DOS fingerprint
+                if energy_reference is not None:
+                    dos_energies_normalized = dos_energies - energy_reference
+                    dos.dos_energies_normalized = dos_energies_normalized
+                    try:
+                        dos_fingerprint = DOSFingerprint().calculate(
+                            dos_energies_normalized.magnitude,
+                            dos_values_normalized,
+                            n_atoms=number_of_atoms
+                        )
+                    except Exception as e:
+                        self.logger.error('could not generate dos fingerprint', exc_info=e)
+                    else:
+                        sec_dos_fingerprint = dos.m_create(section_dos_fingerprint)
+                        sec_dos_fingerprint.bins = dos_fingerprint.bins
+                        sec_dos_fingerprint.indices = dos_fingerprint.indices
+                        sec_dos_fingerprint.stepsize = dos_fingerprint.stepsize
+                        sec_dos_fingerprint.grid_id = dos_fingerprint.grid_id
+                        sec_dos_fingerprint.filling_factor = dos_fingerprint.filling_factor
                 self._backend.closeContext(scc_url)
diff --git a/tests/normalizing/test_dos.py b/tests/normalizing/test_dos.py
index f0d91edf862cf303ca63bf493f4dfd0cb719903f..1fdb73b14173fe4eb0d12a6db1e5f60b2cd4721f 100644
--- a/tests/normalizing/test_dos.py
+++ b/tests/normalizing/test_dos.py
@@ -40,19 +40,19 @@ def test_fingerprint(dos_si_vasp):
 
 
 # def test_dos_energies(dos_si_vasp: Backend, dos_si_exciting: Backend, dos_si_fhiaims: Backend):
-#  """For debugging.
-#  """
-#  x_exciting = dos_si_exciting.get_value('dos_energies_normalized', 0)
-#  y_exciting = dos_si_exciting.get_value('dos_values_normalized', 0)
-#  x_vasp = dos_si_vasp.get_value('dos_energies_normalized', 0)
-#  y_vasp = dos_si_vasp.get_value('dos_values_normalized', 0)
-#  x_fhiaims = dos_si_fhiaims.get_value('dos_energies_normalized', 0)
-#  y_fhiaims = dos_si_fhiaims.get_value('dos_values_normalized', 0)
-#  mpl.plot(x_vasp, y_vasp[0], label="VASP")
-#  mpl.plot(x_exciting, y_exciting[0], label="exciting")
-#  mpl.plot(x_fhiaims, y_fhiaims[0], label="FHI-aims")
-#  mpl.legend()
-#  mpl.show()
+#    """For debugging.
+#    """
+#    x_exciting = dos_si_exciting.get_value('dos_energies_normalized', 0)
+#    y_exciting = dos_si_exciting.get_value('dos_values_normalized', 0)
+#    x_vasp = dos_si_vasp.get_value('dos_energies_normalized', 0)
+#    y_vasp = dos_si_vasp.get_value('dos_values_normalized', 0)
+#    x_fhiaims = dos_si_fhiaims.get_value('dos_energies_normalized', 0)
+#    y_fhiaims = dos_si_fhiaims.get_value('dos_values_normalized', 0)
+#    mpl.plot(x_vasp, y_vasp[0], label="VASP", marker=".")
+#    mpl.plot(x_exciting, y_exciting[0], label="exciting", marker=".")
+#    mpl.plot(x_fhiaims, y_fhiaims[0], label="FHI-aims", marker=".")
+#    mpl.legend()
+#    mpl.show()
 
 
 def test_dos_magnitude(dos_si_vasp: Backend, dos_si_exciting: Backend, dos_si_fhiaims: Backend):