diff --git a/scripts/doc/check-project-params.py b/scripts/doc/check-project-params.py
index c76b7d219031bcba6e66e31ffe0229afc5aa9cd4..4e16bf58bd9efae44fd630a8268b9957d086d773 100755
--- a/scripts/doc/check-project-params.py
+++ b/scripts/doc/check-project-params.py
@@ -12,8 +12,8 @@ github_src_url = "https://github.com/ufz/ogs/tree/master"
 def debug(msg):
     sys.stderr.write(msg+"\n")
 
-if len(sys.argv) != 2:
-    print("USAGE: {} DOCAUXDIR".format(sys.argv[0]))
+if len(sys.argv) != 3:
+    print("USAGE: {} DOCAUXDIR SRCDIR".format(sys.argv[0]))
     sys.exit(1)
 
 docauxdir = sys.argv[1]
@@ -21,10 +21,14 @@ if not os.path.isdir(docauxdir):
     print("error: `{}' is not a directory".format(docauxdir))
     sys.exit(1)
 
+srcdir = sys.argv[2]
+
 undocumented = []
 unneeded_comments = []
 wrong_input = []
 no_doc_page = []
+unneeded_md_files = dict()
+good_tagpaths = set()
 wrong_status = False
 
 for inline in sys.stdin:
@@ -37,10 +41,13 @@ for inline in sys.stdin:
 
         dirs = tag_path_comment.split(".")[:-1]
         p = os.path.join(docauxdir, *dirs)
-        if     (not os.path.isfile(os.path.join(p,                   "t_" + tag_name_comment + ".dox"))) \
-           and (not os.path.isfile(os.path.join(p,                   "a_" + tag_name_comment + ".dox"))) \
-           and (not os.path.isfile(os.path.join(p, tag_name_comment, "i_" + tag_name_comment + ".dox"))) \
-           and (not os.path.isfile(os.path.join(p, tag_name_comment, "c_" + tag_name_comment + ".dox"))) :
+        if os.path.isfile(os.path.join(p, "t_" + tag_name_comment + ".dox")) \
+           or os.path.isfile(os.path.join(p, tag_name_comment, "i_" + tag_name_comment + ".dox")) \
+           or os.path.isfile(os.path.join(p, tag_name_comment, "c_" + tag_name_comment + ".dox")) :
+            good_tagpaths.add((tag_path_comment, "param"))
+        elif os.path.isfile(os.path.join(p, "a_" + tag_name_comment + ".dox")):
+            good_tagpaths.add((tag_path_comment, "attr"))
+        else:
             no_doc_page.append((tag_path_comment, inline[1], inline[2]))
 
     elif status == "WRONGIN":
@@ -60,7 +67,47 @@ for inline in sys.stdin:
         wrong_status = True
 
 
-if (undocumented):
+# traverse dox file hierarchy
+srcdocdir = os.path.join(srcdir, "Documentation", "ProjectFile")
+for (dirpath, _, filenames) in os.walk(srcdocdir):
+    reldirpath = dirpath[len(srcdocdir)+1:]
+
+    for f in filenames:
+        if not f.endswith(".md"): continue
+        filepath = os.path.join(reldirpath, f)
+        tag_or_attr = "param"
+
+        if f.startswith("i_") or f.startswith("c_"):
+            tagpath = reldirpath
+        elif f.startswith("t_"):
+            tagpath = os.path.join(reldirpath, f[2:-len(".md")])
+        elif f.startswith("a_"):
+            tagpath = os.path.join(reldirpath, f[2:-len(".md")])
+            tag_or_attr = "attr"
+        else:
+            debug("ERROR: Found md file with unrecognized name: {}"
+                    .format(filepath))
+            continue
+
+        tagpath = tagpath.replace(os.sep, ".")
+
+        if (tagpath, tag_or_attr) not in good_tagpaths:
+            unneeded_md_files[(tagpath, tag_or_attr)] = filepath
+
+# remove false positives from unneeded_md_files
+if unneeded_md_files:
+    for tagpath, _ in good_tagpaths:
+        tagpath = tagpath.split(".")
+        while tagpath:
+            tagpath.pop()
+            parenttagpath = ".".join(tagpath)
+            if (parenttagpath, "param") in unneeded_md_files:
+                del unneeded_md_files[(parenttagpath, "param")]
+                if not unneeded_md_files: break
+        if not unneeded_md_files: break
+
+
+if undocumented:
     print()
     print("# Undocumented parameters")
     print("| File | Line | Parameter | Type | Method | Link |")
@@ -69,7 +116,7 @@ if (undocumented):
         print(("| {0} | {1} | {3} | <tt>{4}</tt> | <tt>{5}</tt> "
             + "| [&rarr; ufz/ogs/master]({6}/{0}#L{1})").format(*u, github_src_url))
 
-if (unneeded_comments):
+if unneeded_comments:
     print()
     print("# Comments not documenting anything")
     print("| File | Line | Comment | Link |")
@@ -80,7 +127,7 @@ if (unneeded_comments):
         print(("| {0} | {1} | {2} "
             + "| [&rarr; ufz/ogs/master]({3}/{0}#L{1}) |").format(*u2, github_src_url))
 
-if (wrong_input):
+if wrong_input:
     print()
     print("# Lines of input to that script that have not been recognized")
     print("| File | Line | Content | Link |")
@@ -91,7 +138,7 @@ if (wrong_input):
         print(("| {0} | {1} | {2} "
             + "| [&rarr; ufz/ogs/master]({3}/{0}#L{1}) |").format(*w2, github_src_url))
 
-if (no_doc_page):
+if no_doc_page:
     print()
     print("# No documentation page")
     print("| Parameter | File | Line | Link |")
@@ -100,9 +147,21 @@ if (no_doc_page):
         print(("| {0} | {1} | {2} "
             + "| [&rarr; ufz/ogs/master]({3}/{1}#L{2}) |").format(*n, github_src_url))
 
+if unneeded_md_files:
+    print()
+    print("# Documentation pages that are not referenced in the source code")
+    print("| Page | *.md file | Link |")
+    print("| ---- | --------- | ---- |")
+    for (tagpath, tag_or_attr), filepath in sorted(unneeded_md_files.items()):
+        print((r'| \ref ogs_file_{0}__{1} | Documentation/ProjectFile/{2} '
+            + "| [&rarr; ufz/ogs/master]({3}/Documentation/ProjectFile/{2}#) |")
+            .format(tag_or_attr, tagpath.replace(".", "__"),
+                filepath, github_src_url))
+
 # exit with error status if something was not documented.
 if (not not undocumented) or (not not unneeded_comments) \
         or (not not wrong_input) or (not not no_doc_page) \
+        or (not not unneeded_md_files) \
         or wrong_status:
             sys.exit(1)
 
diff --git a/scripts/doc/generate-project-file-doc-qa.sh b/scripts/doc/generate-project-file-doc-qa.sh
index 4c0de98aea96c20576fa7b63897838bad13b1813..96606bef036094ba48e22ca3619cf4ef27ad6ab2 100644
--- a/scripts/doc/generate-project-file-doc-qa.sh
+++ b/scripts/doc/generate-project-file-doc-qa.sh
@@ -37,7 +37,8 @@ If it is empty, there are no issues detected.
 
 EOF
 
-cat "$param_cache" | "$check_quality_script" "$doxdir/ProjectFile" >>"$qafile"
+cat "$param_cache" \
+    | "$check_quality_script" "$doxdir/ProjectFile" "$srcdir" >>"$qafile"
 
 cat <<EOF >>"$qafile"