diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp
index 91b565f..dffa2ca 100644
--- a/redfish-core/src/error_messages.cpp
+++ b/redfish-core/src/error_messages.cpp
@@ -1,18 +1,13 @@
-/*
-Copyright (c) 2018 Intel Corporation
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
+/****************************************************************
+ *                 READ THIS WARNING FIRST
+ * This is an auto-generated header which contains definitions
+ * for Redfish DMTF defined messages.
+ * DO NOT modify this registry outside of running the
+ * parse_registries.py script.  The definitions contained within
+ * this file are owned by DMTF.  Any modifications to these files
+ * should be first pushed to the relevant registry in the DMTF
+ * github organization.
+ ***************************************************************/
 #include "error_messages.hpp"
 
 #include "http_response.hpp"
@@ -33,6 +28,11 @@
 #include <string>
 #include <string_view>
 
+// Clang can't seem to decide whether this header needs to be included or not,
+// and is inconsistent.  Include it for now
+// NOLINTNEXTLINE(misc-include-cleaner)
+#include <utility>
+
 namespace redfish
 {
 
@@ -205,8 +205,8 @@
  */
 nlohmann::json resourceMissingAtURI(const boost::urls::url_view_base& arg1)
 {
-    std::array<std::string_view, 1> args{arg1.buffer()};
-    return getLog(redfish::registries::base::Index::resourceMissingAtURI, args);
+    return getLog(redfish::registries::base::Index::resourceMissingAtURI,
+                  std::to_array<std::string_view>({arg1.buffer()}));
 }
 
 void resourceMissingAtURI(crow::Response& res,
@@ -472,8 +472,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyValueFormatError message into JSON for the specified
- * property
+ * @brief Formats PropertyValueFormatError message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -496,13 +495,11 @@
 
 /**
  * @internal
- * @brief Formats PropertyValueNotInList message into JSON for the specified
- * property
+ * @brief Formats PropertyValueNotInList message into JSON
  *
  * See header file for more information
  * @endinternal
  */
-
 nlohmann::json propertyValueNotInList(const nlohmann::json& arg1,
                                       std::string_view arg2)
 {
@@ -650,9 +647,9 @@
  */
 nlohmann::json stringValueTooLong(std::string_view arg1, int arg2)
 {
-    std::string arg2String = std::to_string(arg2);
+    std::string arg2Str = std::to_string(arg2);
     return getLog(redfish::registries::base::Index::stringValueTooLong,
-                  std::to_array({arg1, std::string_view(arg2String)}));
+                  std::to_array<std::string_view>({arg1, arg2Str}));
 }
 
 void stringValueTooLong(crow::Response& res, std::string_view arg1, int arg2)
@@ -748,7 +745,7 @@
  */
 nlohmann::json chassisPowerStateOnRequired(std::string_view arg1)
 {
-    return getLog(redfish::registries::base::Index::resetRequired,
+    return getLog(redfish::registries::base::Index::chassisPowerStateOnRequired,
                   std::to_array({arg1}));
 }
 
@@ -812,7 +809,6 @@
 {
     std::string arg2Str =
         arg2.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
-
     return getLog(
         redfish::registries::base::Index::propertyValueResourceConflict,
         std::to_array<std::string_view>({arg1, arg2Str, arg3.buffer()}));
@@ -839,7 +835,6 @@
 {
     std::string arg2Str =
         arg2.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
-
     return getLog(
         redfish::registries::base::Index::propertyValueExternalConflict,
         std::to_array<std::string_view>({arg1, arg2Str}));
@@ -988,8 +983,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyValueTypeError message into JSON for the specified
- * property
+ * @brief Formats PropertyValueTypeError message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1012,8 +1006,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyValueError message into JSON for the specified
- * property
+ * @brief Formats PropertyValueError message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1021,7 +1014,7 @@
 nlohmann::json propertyValueError(std::string_view arg1)
 {
     return getLog(redfish::registries::base::Index::propertyValueError,
-                  std::to_array<std::string_view>({arg1}));
+                  std::to_array({arg1}));
 }
 
 void propertyValueError(crow::Response& res, std::string_view arg1)
@@ -1032,7 +1025,7 @@
 
 /**
  * @internal
- * @brief Formats ResourceNotFound message into JSONd
+ * @brief Formats ResourceNotFound message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1073,8 +1066,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyNotWritable message into JSON for the specified
- * property
+ * @brief Formats PropertyNotWritable message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1326,8 +1318,6 @@
 
 void success(crow::Response& res)
 {
-    // don't set res.result here because success is the default and any
-    // error should overwrite the default
     addMessageToJsonRoot(res.jsonValue, success());
 }
 
@@ -1369,8 +1359,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyUnknown message into JSON for the specified
- * property
+ * @brief Formats PropertyUnknown message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1470,7 +1459,7 @@
 
 /**
  * @internal
- * @brief Formats actionParameterValueError message into JSON
+ * @brief Formats ActionParameterValueError message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1727,8 +1716,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyMissing message into JSON for the specified
- * property
+ * @brief Formats PropertyMissing message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1804,12 +1792,6 @@
                           queryParameterOutOfRange(arg1, arg2, arg3));
 }
 
-nlohmann::json passwordChangeRequired(const boost::urls::url_view_base& arg1)
-{
-    return getLog(redfish::registries::base::Index::passwordChangeRequired,
-                  std::to_array<std::string_view>({arg1.buffer()}));
-}
-
 /**
  * @internal
  * @brief Formats PasswordChangeRequired message into JSON
@@ -1817,10 +1799,16 @@
  * See header file for more information
  * @endinternal
  */
+nlohmann::json passwordChangeRequired(const boost::urls::url_view_base& arg1)
+{
+    return getLog(redfish::registries::base::Index::passwordChangeRequired,
+                  std::to_array<std::string_view>({arg1.buffer()}));
+}
+
 void passwordChangeRequired(crow::Response& res,
                             const boost::urls::url_view_base& arg1)
 {
-    messages::addMessageToJsonRoot(res.jsonValue, passwordChangeRequired(arg1));
+    addMessageToJsonRoot(res.jsonValue, passwordChangeRequired(arg1));
 }
 
 /**
@@ -1879,12 +1867,6 @@
     addMessageToErrorJson(res.jsonValue, arraySizeTooLong(arg1, arg2));
 }
 
-nlohmann::json generateSecretKeyRequired(const boost::urls::url_view_base& arg1)
-{
-    return getLog(redfish::registries::base::Index::generateSecretKeyRequired,
-                  std::to_array<std::string_view>({arg1.buffer()}));
-}
-
 /**
  * @internal
  * @brief Formats GenerateSecretKeyRequired message into JSON
@@ -1892,13 +1874,563 @@
  * See header file for more information
  * @endinternal
  */
+nlohmann::json generateSecretKeyRequired(const boost::urls::url_view_base& arg1)
+{
+    return getLog(redfish::registries::base::Index::generateSecretKeyRequired,
+                  std::to_array<std::string_view>({arg1.buffer()}));
+}
+
 void generateSecretKeyRequired(crow::Response& res,
                                const boost::urls::url_view_base& arg1)
 {
-    messages::addMessageToJsonRoot(res.jsonValue,
-                                   generateSecretKeyRequired(arg1));
+    res.result(boost::beast::http::status::forbidden);
+    addMessageToErrorJson(res.jsonValue, generateSecretKeyRequired(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats PropertyNotUpdated message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json propertyNotUpdated(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::propertyNotUpdated,
+                  std::to_array({arg1}));
+}
+
+void propertyNotUpdated(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, propertyNotUpdated(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats InvalidJSON message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json invalidJSON(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::invalidJSON,
+                  std::to_array({arg1}));
+}
+
+void invalidJSON(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, invalidJSON(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats ActionParameterValueOutOfRange message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json actionParameterValueOutOfRange(
+    std::string_view arg1, std::string_view arg2, std::string_view arg3)
+{
+    return getLog(
+        redfish::registries::base::Index::actionParameterValueOutOfRange,
+        std::to_array({arg1, arg2, arg3}));
+}
+
+void actionParameterValueOutOfRange(crow::Response& res, std::string_view arg1,
+                                    std::string_view arg2,
+                                    std::string_view arg3)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue,
+                          actionParameterValueOutOfRange(arg1, arg2, arg3));
+}
+
+/**
+ * @internal
+ * @brief Formats ArraySizeTooShort message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json arraySizeTooShort(std::string_view arg1, std::string_view arg2)
+{
+    return getLog(redfish::registries::base::Index::arraySizeTooShort,
+                  std::to_array({arg1, arg2}));
+}
+
+void arraySizeTooShort(crow::Response& res, std::string_view arg1,
+                       std::string_view arg2)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, arraySizeTooShort(arg1, arg2));
+}
+
+/**
+ * @internal
+ * @brief Formats QueryParameterValueError message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json queryParameterValueError(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::queryParameterValueError,
+                  std::to_array({arg1}));
+}
+
+void queryParameterValueError(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, queryParameterValueError(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats QueryParameterUnsupported message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json queryParameterUnsupported(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::queryParameterUnsupported,
+                  std::to_array({arg1}));
+}
+
+void queryParameterUnsupported(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, queryParameterUnsupported(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats PayloadTooLarge message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json payloadTooLarge()
+{
+    return getLog(redfish::registries::base::Index::payloadTooLarge, {});
+}
+
+void payloadTooLarge(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, payloadTooLarge());
+}
+
+/**
+ * @internal
+ * @brief Formats MissingOrMalformedPart message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json missingOrMalformedPart()
+{
+    return getLog(redfish::registries::base::Index::missingOrMalformedPart, {});
+}
+
+void missingOrMalformedPart(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, missingOrMalformedPart());
+}
+
+/**
+ * @internal
+ * @brief Formats InvalidURI message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json invalidURI(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::invalidURI,
+                  std::to_array({arg1}));
+}
+
+void invalidURI(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, invalidURI(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats StringValueTooShort message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json stringValueTooShort(std::string_view arg1, std::string_view arg2)
+{
+    return getLog(redfish::registries::base::Index::stringValueTooShort,
+                  std::to_array({arg1, arg2}));
+}
+
+void stringValueTooShort(crow::Response& res, std::string_view arg1,
+                         std::string_view arg2)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, stringValueTooShort(arg1, arg2));
+}
+
+/**
+ * @internal
+ * @brief Formats ResetRecommended message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json resetRecommended(std::string_view arg1, std::string_view arg2)
+{
+    return getLog(redfish::registries::base::Index::resetRecommended,
+                  std::to_array({arg1, arg2}));
+}
+
+void resetRecommended(crow::Response& res, std::string_view arg1,
+                      std::string_view arg2)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, resetRecommended(arg1, arg2));
+}
+
+/**
+ * @internal
+ * @brief Formats ActionParameterValueConflict message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json
+    actionParameterValueConflict(std::string_view arg1, std::string_view arg2)
+{
+    return getLog(
+        redfish::registries::base::Index::actionParameterValueConflict,
+        std::to_array({arg1, arg2}));
+}
+
+void actionParameterValueConflict(crow::Response& res, std::string_view arg1,
+                                  std::string_view arg2)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue,
+                          actionParameterValueConflict(arg1, arg2));
+}
+
+/**
+ * @internal
+ * @brief Formats HeaderMissing message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json headerMissing(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::headerMissing,
+                  std::to_array({arg1}));
+}
+
+void headerMissing(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, headerMissing(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats HeaderInvalid message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json headerInvalid(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::headerInvalid,
+                  std::to_array({arg1}));
+}
+
+void headerInvalid(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, headerInvalid(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats UndeterminedFault message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json undeterminedFault(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::undeterminedFault,
+                  std::to_array({arg1}));
+}
+
+void undeterminedFault(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, undeterminedFault(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats ConditionInRelatedResource message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json conditionInRelatedResource()
+{
+    return getLog(redfish::registries::base::Index::conditionInRelatedResource,
+                  {});
+}
+
+void conditionInRelatedResource(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, conditionInRelatedResource());
+}
+
+/**
+ * @internal
+ * @brief Formats RestrictedRole message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json restrictedRole(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::restrictedRole,
+                  std::to_array({arg1}));
+}
+
+void restrictedRole(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, restrictedRole(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats RestrictedPrivilege message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json restrictedPrivilege(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::restrictedPrivilege,
+                  std::to_array({arg1}));
+}
+
+void restrictedPrivilege(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, restrictedPrivilege(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats PropertyDeprecated message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json propertyDeprecated(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::propertyDeprecated,
+                  std::to_array({arg1}));
+}
+
+void propertyDeprecated(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, propertyDeprecated(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats ResourceDeprecated message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json resourceDeprecated(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::resourceDeprecated,
+                  std::to_array({arg1}));
+}
+
+void resourceDeprecated(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, resourceDeprecated(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats PropertyValueDeprecated message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json propertyValueDeprecated(std::string_view arg1,
+                                       std::string_view arg2)
+{
+    return getLog(redfish::registries::base::Index::propertyValueDeprecated,
+                  std::to_array({arg1, arg2}));
+}
+
+void propertyValueDeprecated(crow::Response& res, std::string_view arg1,
+                             std::string_view arg2)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, propertyValueDeprecated(arg1, arg2));
+}
+
+/**
+ * @internal
+ * @brief Formats ActionDeprecated message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json actionDeprecated(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::actionDeprecated,
+                  std::to_array({arg1}));
+}
+
+void actionDeprecated(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, actionDeprecated(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats NetworkNameResolutionNotConfigured message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json networkNameResolutionNotConfigured()
+{
+    return getLog(
+        redfish::registries::base::Index::networkNameResolutionNotConfigured,
+        {});
+}
+
+void networkNameResolutionNotConfigured(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, networkNameResolutionNotConfigured());
+}
+
+/**
+ * @internal
+ * @brief Formats NetworkNameResolutionNotSupported message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json networkNameResolutionNotSupported()
+{
+    return getLog(
+        redfish::registries::base::Index::networkNameResolutionNotSupported,
+        {});
+}
+
+void networkNameResolutionNotSupported(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, networkNameResolutionNotSupported());
+}
+
+/**
+ * @internal
+ * @brief Formats AuthenticationTokenRequired message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json authenticationTokenRequired()
+{
+    return getLog(redfish::registries::base::Index::authenticationTokenRequired,
+                  {});
+}
+
+void authenticationTokenRequired(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, authenticationTokenRequired());
+}
+
+/**
+ * @internal
+ * @brief Formats OneTimePasscodeSent message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json oneTimePasscodeSent(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::oneTimePasscodeSent,
+                  std::to_array({arg1}));
+}
+
+void oneTimePasscodeSent(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, oneTimePasscodeSent(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats LicenseRequired message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json licenseRequired(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::licenseRequired,
+                  std::to_array({arg1}));
+}
+
+void licenseRequired(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, licenseRequired(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats PropertyModified message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json propertyModified()
+{
+    return getLog(redfish::registries::base::Index::propertyModified, {});
+}
+
+void propertyModified(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, propertyModified());
 }
 
 } // namespace messages
-
 } // namespace redfish
diff --git a/scripts/parse_registries.py b/scripts/parse_registries.py
index 194f134..573f8a7 100755
--- a/scripts/parse_registries.py
+++ b/scripts/parse_registries.py
@@ -188,6 +188,54 @@
 )
 
 
+def get_response_code(entry_id, entry):
+    codes = {
+        "InternalError": "internal_server_error",
+        "OperationTimeout": "internal_server_error",
+        "PropertyValueResourceConflict": "conflict",
+        "ResourceInUse": "service_unavailable",
+        "ServiceTemporarilyUnavailable": "service_unavailable",
+        "ResourceCannotBeDeleted": "method_not_allowed",
+        "PropertyValueModified": "ok",
+        "InsufficientPrivilege": "forbidden",
+        "AccountForSessionNoLongerExists": "forbidden",
+        "ServiceDisabled": "service_unavailable",
+        "ServiceInUnknownState": "service_unavailable",
+        "EventSubscriptionLimitExceeded": "service_unavailable",
+        "ResourceAtUriUnauthorized": "unauthorized",
+        "SessionTerminated": "ok",
+        "SubscriptionTerminated": "ok",
+        "PropertyNotWritable": "forbidden",
+        "MaximumErrorsExceeded": "internal_server_error",
+        "GeneralError": "internal_server_error",
+        "PreconditionFailed": "precondition_failed",
+        "OperationFailed": "bad_gateway",
+        "ServiceShuttingDown": "service_unavailable",
+        "AccountRemoved": "ok",
+        "PropertyValueExternalConflict": "conflict",
+        "InsufficientStorage": "insufficient_storage",
+        "OperationNotAllowed": "method_not_allowed",
+        "ResourceNotFound": "not_found",
+        "CouldNotEstablishConnection": "not_found",
+        "AccessDenied": "forbidden",
+        "Success": None,
+        "Created": "created",
+        "NoValidSession": "forbidden",
+        "SessionLimitExceeded": "service_unavailable",
+        "ResourceExhaustion": "service_unavailable",
+        "AccountModified": "ok",
+        "PasswordChangeRequired": None,
+        "ResourceInStandby": "service_unavailable",
+        "GenerateSecretKeyRequired": "forbidden",
+    }
+
+    code = codes.get(entry_id, "NOCODE")
+    if code != "NOCODE":
+        return code
+
+    return "bad_request"
+
+
 def get_old_index(entry):
     old_order = [
         "ResourceInUse",
@@ -285,7 +333,7 @@
         return 999999
 
 
-def create_error_registry(entry):
+def make_error_function(entry_id, entry, is_header):
 
     arg_as_url = {
         "AccessDenied": [1],
@@ -329,6 +377,128 @@
         "InvalidIndex": [1],
     }
 
+    out = ""
+    args = []
+    argtypes = []
+    for arg_index, arg in enumerate(entry.get("ParamTypes", [])):
+        arg_index += 1
+        if arg_index in arg_as_url.get(entry_id, []):
+            typename = "const boost::urls::url_view_base&"
+        elif arg_index in arg_as_json.get(entry_id, []):
+            typename = "const nlohmann::json&"
+        elif arg_index in arg_as_int.get(entry_id, []):
+            typename = "int"
+        elif arg_index in arg_as_uint64.get(entry_id, []):
+            typename = "uint64_t"
+        elif arg_index in arg_as_int64.get(entry_id, []):
+            typename = "int64_t"
+        else:
+            typename = "std::string_view"
+        argtypes.append(typename)
+        args.append(f"{typename} arg{arg_index}")
+    function_name = entry_id[0].lower() + entry_id[1:]
+    arg = ", ".join(args)
+    out += f"nlohmann::json {function_name}({arg})"
+
+    if is_header:
+        out += ";\n\n"
+    else:
+        out += "\n{\n"
+        to_array_type = ""
+        if argtypes:
+            outargs = []
+            for index, typename in enumerate(argtypes):
+                index += 1
+                if typename == "const nlohmann::json&":
+                    out += f"std::string arg{index}Str = arg{index}.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);\n"
+                elif typename in ("int64_t", "int", "uint64_t"):
+                    out += f"std::string arg{index}Str = std::to_string(arg{index});\n"
+
+            for index, typename in enumerate(argtypes):
+                index += 1
+                if typename == "const boost::urls::url_view_base&":
+                    outargs.append(f"arg{index}.buffer()")
+                    to_array_type = "<std::string_view>"
+                elif typename == "const nlohmann::json&":
+                    outargs.append(f"arg{index}Str")
+                    to_array_type = "<std::string_view>"
+                elif typename in ("int64_t", "int", "uint64_t"):
+                    outargs.append(f"arg{index}Str")
+                    to_array_type = "<std::string_view>"
+                else:
+                    outargs.append(f"arg{index}")
+            argstring = ", ".join(outargs)
+            # out += f"    std::array<std::string_view, {len(argtypes)}> args{{{argstring}}};\n"
+
+        if argtypes:
+            arg_param = f"std::to_array{to_array_type}({{{argstring}}})"
+        else:
+            arg_param = "{}"
+        out += f"    return getLog(redfish::registries::base::Index::{function_name}, {arg_param});"
+        out += "\n}\n\n"
+    args.insert(0, "crow::Response& res")
+    if entry_id == "InternalError":
+        if is_header:
+            args.append(
+                "std::source_location location = std::source_location::current()"
+            )
+        else:
+            args.append("const std::source_location location")
+    arg = ", ".join(args)
+    out += f"void {function_name}({arg})"
+    if is_header:
+        out += ";\n"
+    else:
+        out += "\n{\n"
+        if entry_id == "InternalError":
+            out += """BMCWEB_LOG_CRITICAL("Internal Error {}({}:{}) `{}`: ", location.file_name(),
+                        location.line(), location.column(),
+                        location.function_name());\n"""
+
+        if entry_id == "ServiceTemporarilyUnavailable":
+            out += (
+                "res.addHeader(boost::beast::http::field::retry_after, arg1);"
+            )
+
+        res = get_response_code(entry_id, entry)
+        if res:
+            out += f"    res.result(boost::beast::http::status::{res});\n"
+        args_out = ", ".join([f"arg{x+1}" for x in range(len(argtypes))])
+
+        addMessageToJson = {
+            "PropertyDuplicate": 1,
+            "ResourceAlreadyExists": 2,
+            "CreateFailedMissingReqProperties": 1,
+            "PropertyValueFormatError": 2,
+            "PropertyValueNotInList": 2,
+            "PropertyValueTypeError": 2,
+            "PropertyValueError": 1,
+            "PropertyNotWritable": 1,
+            "PropertyValueModified": 1,
+            "PropertyMissing": 1,
+        }
+
+        addMessageToRoot = [
+            "SessionTerminated",
+            "SubscriptionTerminated",
+            "AccountRemoved",
+            "Created",
+            "Success",
+            "PasswordChangeRequired",
+        ]
+
+        if entry_id in addMessageToJson:
+            out += f"    addMessageToJson(res.jsonValue, {function_name}({args_out}), arg{addMessageToJson[entry_id]});\n"
+        elif entry_id in addMessageToRoot:
+            out += f"    addMessageToJsonRoot(res.jsonValue, {function_name}({args_out}));\n"
+        else:
+            out += f"    addMessageToErrorJson(res.jsonValue, {function_name}({args_out}));\n"
+        out += "}\n"
+    out += "\n"
+    return out
+
+
+def create_error_registry(entry):
     file, json_dict, namespace, url = entry
 
     messages = OrderedDict(
@@ -396,35 +566,191 @@
             out.write("*\n")
             out.write(f"* @returns Message {entry_id} formatted to JSON */\n")
 
-            args = []
-            for arg_index, arg in enumerate(entry.get("ParamTypes", [])):
-                arg_index += 1
-                if arg_index in arg_as_url.get(entry_id, []):
-                    typename = "const boost::urls::url_view_base&"
-                elif arg_index in arg_as_json.get(entry_id, []):
-                    typename = "const nlohmann::json&"
-                elif arg_index in arg_as_int.get(entry_id, []):
-                    typename = "int"
-                elif arg_index in arg_as_uint64.get(entry_id, []):
-                    typename = "uint64_t"
-                elif arg_index in arg_as_int64.get(entry_id, []):
-                    typename = "int64_t"
-                else:
-                    typename = "std::string_view"
-                args.append(f"{typename} arg{arg_index}")
-            function_name = entry_id[0].lower() + entry_id[1:]
-            arg = ", ".join(args)
-            out.write(f"nlohmann::json {function_name}({arg});\n\n")
-            args.insert(0, "crow::Response& res")
-            if entry_id == "InternalError":
-                args.append(
-                    "std::source_location location = std::source_location::current()"
-                )
-            arg = ", ".join(args)
-            out.write(f"void {function_name}({arg});\n\n")
+            out.write(make_error_function(entry_id, entry, True))
         out.write("    }\n")
         out.write("}\n")
-    os.system(f"clang-format -i {error_messages_hpp}")
+
+    error_messages_cpp = os.path.join(
+        SCRIPT_DIR, "..", "redfish-core", "src", "error_messages.cpp"
+    )
+    with open(
+        error_messages_cpp,
+        "w",
+    ) as out:
+        out.write(WARNING)
+        out.write(
+            """
+#include "error_messages.hpp"
+
+#include "http_response.hpp"
+#include "logging.hpp"
+#include "registries.hpp"
+#include "registries/base_message_registry.hpp"
+
+#include <boost/beast/http/field.hpp>
+#include <boost/beast/http/status.hpp>
+#include <boost/url/url_view_base.hpp>
+#include <nlohmann/json.hpp>
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <source_location>
+#include <span>
+#include <string>
+#include <string_view>
+
+// Clang can't seem to decide whether this header needs to be included or not,
+// and is inconsistent.  Include it for now
+// NOLINTNEXTLINE(misc-include-cleaner)
+#include <utility>
+
+namespace redfish
+{
+
+namespace messages
+{
+
+static void addMessageToErrorJson(nlohmann::json& target,
+                                  const nlohmann::json& message)
+{
+    auto& error = target["error"];
+
+    // If this is the first error message, fill in the information from the
+    // first error message to the top level struct
+    if (!error.is_object())
+    {
+        auto messageIdIterator = message.find("MessageId");
+        if (messageIdIterator == message.end())
+        {
+            BMCWEB_LOG_CRITICAL(
+                "Attempt to add error message without MessageId");
+            return;
+        }
+
+        auto messageFieldIterator = message.find("Message");
+        if (messageFieldIterator == message.end())
+        {
+            BMCWEB_LOG_CRITICAL("Attempt to add error message without Message");
+            return;
+        }
+        error["code"] = *messageIdIterator;
+        error["message"] = *messageFieldIterator;
+    }
+    else
+    {
+        // More than 1 error occurred, so the message has to be generic
+        error["code"] = std::string(messageVersionPrefix) + "GeneralError";
+        error["message"] = "A general error has occurred. See Resolution for "
+                           "information on how to resolve the error.";
+    }
+
+    // This check could technically be done in the default construction
+    // branch above, but because we need the pointer to the extended info field
+    // anyway, it's more efficient to do it here.
+    auto& extendedInfo = error[messages::messageAnnotation];
+    if (!extendedInfo.is_array())
+    {
+        extendedInfo = nlohmann::json::array();
+    }
+
+    extendedInfo.push_back(message);
+}
+
+void moveErrorsToErrorJson(nlohmann::json& target, nlohmann::json& source)
+{
+    if (!source.is_object())
+    {
+        return;
+    }
+    auto errorIt = source.find("error");
+    if (errorIt == source.end())
+    {
+        // caller puts error message in root
+        messages::addMessageToErrorJson(target, source);
+        source.clear();
+        return;
+    }
+    auto extendedInfoIt = errorIt->find(messages::messageAnnotation);
+    if (extendedInfoIt == errorIt->end())
+    {
+        return;
+    }
+    const nlohmann::json::array_t* extendedInfo =
+        (*extendedInfoIt).get_ptr<const nlohmann::json::array_t*>();
+    if (extendedInfo == nullptr)
+    {
+        source.erase(errorIt);
+        return;
+    }
+    for (const nlohmann::json& message : *extendedInfo)
+    {
+        addMessageToErrorJson(target, message);
+    }
+    source.erase(errorIt);
+}
+
+static void addMessageToJsonRoot(nlohmann::json& target,
+                                 const nlohmann::json& message)
+{
+    if (!target[messages::messageAnnotation].is_array())
+    {
+        // Force object to be an array
+        target[messages::messageAnnotation] = nlohmann::json::array();
+    }
+
+    target[messages::messageAnnotation].push_back(message);
+}
+
+static void addMessageToJson(nlohmann::json& target,
+                             const nlohmann::json& message,
+                             std::string_view fieldPath)
+{
+    std::string extendedInfo(fieldPath);
+    extendedInfo += messages::messageAnnotation;
+
+    nlohmann::json& field = target[extendedInfo];
+    if (!field.is_array())
+    {
+        // Force object to be an array
+        field = nlohmann::json::array();
+    }
+
+    // Object exists and it is an array so we can just push in the message
+    field.push_back(message);
+}
+
+static nlohmann::json getLog(redfish::registries::base::Index name,
+                             std::span<const std::string_view> args)
+{
+    size_t index = static_cast<size_t>(name);
+    if (index >= redfish::registries::base::registry.size())
+    {
+        return {};
+    }
+    return getLogFromRegistry(redfish::registries::base::header,
+                              redfish::registries::base::registry, index, args);
+}
+
+"""
+        )
+        for entry_id, entry in messages.items():
+            out.write(
+                f"""/**
+ * @internal
+ * @brief Formats {entry_id} message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+"""
+            )
+            message = entry["Message"]
+            out.write(make_error_function(entry_id, entry, False))
+
+        out.write("    }\n")
+        out.write("}\n")
+    os.system(f"clang-format -i {error_messages_hpp} {error_messages_cpp}")
 
 
 def make_privilege_registry():
