diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index 96d78b0f00bb0118e660de667b8f1cb0392e09dd..8c22a5d712a526ed328ad5a2a7be0b0a175b9f7b 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -4790,3 +4790,22 @@ DynamicModel::checkNoRemainingPacTargetNonstationary() const
         exit(EXIT_FAILURE);
       }
 }
+
+void
+DynamicModel::checkIsLinear() const
+{
+  if (!nonzero_hessian_eqs.empty())
+    {
+      cerr << "ERROR: If the model is declared linear the second derivatives must be equal to zero." << endl
+           << "       The following equations have non-zero second derivatives:" << endl;
+      for (auto it : nonzero_hessian_eqs)
+        {
+          cerr << "       * Eq # " << it+1;
+          if (optional<string> eqname { equation_tags.getTagValueByEqnAndKey(it, "name") };
+              eqname)
+            cerr << " [" << *eqname << "]";
+          cerr << endl;
+        }
+      exit(EXIT_FAILURE);
+    }
+}
diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh
index fb276f9b0f4794f7e745b76310fdbe64895c6bdd..a71b08cc222cc9e36db2ee1c19d03d48c951de37 100644
--- a/src/DynamicModel.hh
+++ b/src/DynamicModel.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2003-2022 Dynare Team
+ * Copyright © 2003-2023 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -372,12 +372,13 @@ public:
   {
     return computed_derivs_order >= 2;
   }
-  //! Returns equations that have non-zero second derivatives
-  set<int>
-  getNonZeroHessianEquations() const
-  {
-    return nonzero_hessian_eqs;
-  }
+
+  /* Check whether the model is linear, by verifying that the hessian is zero,
+     and error out otherwise.
+     Must be called after computingPass().
+     FIXME: this check always passes if derivsOrder = 1, i.e. for a perfect
+     foresight model, because the Hessian is not computed in that case. */
+  void checkIsLinear() const;
 
   //! Fill the trend component model table with information available from the transformed model
   void fillTrendComponentModelTable() const;
diff --git a/src/ModFile.cc b/src/ModFile.cc
index a582b9666f38022fef73285e4d9839444aaf5401..326155b27f8425a11e1f4da083fe8caa4702a62d 100644
--- a/src/ModFile.cc
+++ b/src/ModFile.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2006-2022 Dynare Team
+ * Copyright © 2006-2023 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -738,30 +738,11 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o
       else // No computing task requested, compute derivatives up to 2nd order by default
         dynamic_model.computingPass(2, 0, global_eval_context, no_tmp_terms, block, use_dll);
 
-      /* Check that the model is linear.
-         FIXME: this check always passes if derivsOrder = 1, i.e. for a perfect
-         foresight model, because the Hessian is not computed in that case. */
       if (linear)
-        {
-          set<int> eqs = mod_file_struct.ramsey_model_present ?
-            orig_ramsey_dynamic_model.getNonZeroHessianEquations() :
-            dynamic_model.getNonZeroHessianEquations();
-
-          if (!eqs.empty())
-            {
-              cerr << "ERROR: If the model is declared linear the second derivatives must be equal to zero." << endl
-                   << "       The following equations have non-zero second derivatives:" << endl;
-              for (const auto &it : eqs)
-                {
-                  cerr << "       * Eq # " << it+1;
-                  auto tags = dynamic_model.getEquationTags(it);
-                  if (auto it2 = tags.find("name"); it2 != tags.end())
-                    cerr << " [" << it2->second << "]";
-                  cerr << endl;
-                }
-              exit(EXIT_FAILURE);
-            }
-        }
+        if (mod_file_struct.ramsey_model_present)
+          orig_ramsey_dynamic_model.checkIsLinear();
+        else
+          dynamic_model.checkIsLinear();
     }
 
   // Those matrices can only be filled here, because we use derivatives
diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index 1986485b059bc8f3b713bce528ec56e823a36a11..ee42a36baa701ca3b951c9d9eecdbb5aba3bb6a2 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2003-2022 Dynare Team
+ * Copyright © 2003-2023 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -1418,8 +1418,7 @@ void
 ModelTree::findConstantEquationsWithoutMcpTag(map<VariableNode *, NumConstNode *> &subst_table) const
 {
   for (size_t i = 0; i < equations.size(); i++)
-    if (auto tags = getEquationTags(i);
-        tags.find("mcp") == tags.end())
+    if (!equation_tags.exists(i, "mcp"))
       equations[i]->findConstantEquations(subst_table);
 }
 
@@ -1587,7 +1586,7 @@ ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const
           if (equations_lineno[eq])
             output << R"(, "line": )" << *equations_lineno[eq];
 
-          if (auto eqtags = getEquationTags(eq);
+          if (auto eqtags = equation_tags.getTagsByEqn(eq);
               !eqtags.empty())
             {
               output << R"(, "tags": {)";
diff --git a/src/ModelTree.hh b/src/ModelTree.hh
index 3e1533f655855acfd3a39fce31f089fb51af6e28..6156a511f1a28248d7c4e959e34fea14c1399d90 100644
--- a/src/ModelTree.hh
+++ b/src/ModelTree.hh
@@ -659,13 +659,6 @@ public:
   // Waits until the MEX compilation queue is empty
   static void waitForMEXCompilationWorkers();
 
-  //! Returns all the equation tags associated to an equation
-  map<string, string>
-  getEquationTags(int eq) const
-  {
-    return equation_tags.getTagsByEqn(eq);
-  }
-
   //! Returns the vector of non-zero derivative counts
   const vector<int> &
   getNNZDerivatives() const