diff --git a/common/cpp/include/asapo/common/error.h b/common/cpp/include/asapo/common/error.h
index fe6b93bf7efbe16a61dd23e2a539135f7d186653..8d045179f7d48c57df2445327b419f5b4b4e6992 100644
--- a/common/cpp/include/asapo/common/error.h
+++ b/common/cpp/include/asapo/common/error.h
@@ -5,6 +5,7 @@
 #include <memory>
 #include <utility>
 #include <ostream>
+#include <map>
 
 namespace asapo {
 
@@ -18,11 +19,10 @@ using Error = std::unique_ptr<ErrorInterface>;
 class ErrorInterface {
   public:
     virtual std::string Explain() const noexcept = 0;
+    virtual std::string ExplainPretty(uint8_t shift = 0) const noexcept = 0;
     virtual std::string ExplainInJSON() const noexcept = 0;
-    virtual void Append(const std::string& value) noexcept = 0;
-    virtual void Prepend(const std::string& value) noexcept = 0;
-    virtual ErrorInterface* AddContext(std::string context) noexcept = 0;
-    virtual ErrorInterface* AddCause(Error cause_err) noexcept = 0;
+    virtual ErrorInterface* AddContext(std::string key, std::string value) noexcept = 0;
+    virtual ErrorInterface* SetCause(Error cause_err) noexcept = 0;
     virtual CustomErrorData* GetCustomData() noexcept = 0;
     virtual void SetCustomData(std::unique_ptr<CustomErrorData> data) noexcept = 0;
     virtual ~ErrorInterface() = default; // needed for unique_ptr to delete itself
@@ -49,7 +49,7 @@ class ServiceError : public ErrorInterface {
     ServiceErrorType error_type_;
     std::string error_name_;
     std::string error_message_;
-    std::string context_;
+    std::map<std::string, std::string> context_;
     Error cause_err_;
     std::unique_ptr<CustomErrorData> custom_data_;
   public:
@@ -57,11 +57,10 @@ class ServiceError : public ErrorInterface {
     ServiceErrorType GetServiceErrorType() const noexcept;
     CustomErrorData* GetCustomData() noexcept override;
     void SetCustomData(std::unique_ptr<CustomErrorData> data) noexcept override;
-    void Append(const std::string& value) noexcept override;
-    void Prepend(const std::string& value) noexcept override;
-    ErrorInterface* AddContext(std::string context) noexcept override;
-    ErrorInterface* AddCause(Error cause_err) noexcept override;
+    ErrorInterface* AddContext(std::string key, std::string value) noexcept override;
+    ErrorInterface* SetCause(Error cause_err) noexcept override;
     std::string Explain() const noexcept override;
+    virtual std::string ExplainPretty(uint8_t shift) const noexcept override;
     std::string ExplainInJSON() const noexcept override;
 };
 
@@ -139,15 +138,15 @@ using GeneralError = ServiceError<GeneralErrorType>;
 using GeneralErrorTemplate = ServiceErrorTemplate<GeneralErrorType>;
 
 auto const kMemoryAllocationError = GeneralErrorTemplate {
-    "kMemoryAllocationError", GeneralErrorType::kMemoryAllocationError
+    "memory allocation", GeneralErrorType::kMemoryAllocationError
 };
 
 auto const kEndOfFile = GeneralErrorTemplate {
-    "End of file", GeneralErrorType::kEndOfFile
+    "end of file", GeneralErrorType::kEndOfFile
 };
 
 auto const kSimpleError = GeneralErrorTemplate {
-    "", GeneralErrorType::kSimpleError
+    "unnamed error", GeneralErrorType::kSimpleError
 };
 
 }
diff --git a/common/cpp/include/asapo/common/error.tpp b/common/cpp/include/asapo/common/error.tpp
index edbb36eb25c79d66cdd8208e982e18e0b446f9fc..d0a2807d0840f4e2e5685d784391b586c354b218 100644
--- a/common/cpp/include/asapo/common/error.tpp
+++ b/common/cpp/include/asapo/common/error.tpp
@@ -30,34 +30,82 @@ void ServiceError<ServiceErrorType>::SetCustomData(std::unique_ptr<CustomErrorDa
 }
 
 template<typename ServiceErrorType>
-void ServiceError<ServiceErrorType>::Append(const std::string &value) noexcept {
-    error_message_ += (error_message_.empty() ? "" : ": ") + value;
-}
-
-template<typename ServiceErrorType>
-void ServiceError<ServiceErrorType>::Prepend(const std::string &value) noexcept {
-    error_message_ = value + (error_message_.empty() ? "" : ": ") + error_message_;
+std::string ServiceError<ServiceErrorType>::ExplainPretty(uint8_t shift) const noexcept {
+    std::string base_shift(static_cast<size_t>(shift), ' ');
+    std::string shift_s(static_cast<size_t>(2), ' ');
+    std::string err = base_shift + "error: " + error_name_;
+    if (!error_message_.empty()) {
+        err += "\n" + base_shift + shift_s + "message: " + error_message_;
+    }
+    if (!context_.empty()) {
+        err += "\n" + base_shift + shift_s + "context: ";
+        auto i = 0;
+        for (const auto &kv : context_) {
+            err += (i > 0 ? ", " : "") + kv.first + ":" + kv.second;
+            i++;
+        }
+    }
+    if (cause_err_ != nullptr) {
+        err += "\n" + base_shift + shift_s + "caused by: ";
+        err += "\n" + base_shift + shift_s + cause_err_->ExplainPretty(shift + 2);
+    }
+    return err;
 }
 
 template<typename ServiceErrorType>
 std::string ServiceError<ServiceErrorType>::Explain() const noexcept {
-    return error_name_ + (error_message_.empty() ? "" : ": ") + error_message_;
+    std::string err = "error: " + error_name_;
+    if (!error_message_.empty()) {
+        err += "; message: " + error_message_;
+    }
+    if (!context_.empty()) {
+        err += "; context: ";
+        auto i = 0;
+        for (const auto &kv : context_) {
+            err += (i > 0 ? ", " : "") + kv.first + ":" + kv.second;
+            i++;
+        }
+    }
+    if (cause_err_ != nullptr) {
+        err +=  "; caused by: " + cause_err_->Explain() ;
+    }
+    return err;
 }
 
 template<typename ServiceErrorType>
-ErrorInterface *ServiceError<ServiceErrorType>::AddContext(std::string context) noexcept {
-    context_ = std::move(context);
+ErrorInterface *ServiceError<ServiceErrorType>::AddContext(std::string key, std::string value) noexcept {
+    context_[std::move(key)] = std::move(value);
     return this;
 }
 template<typename ServiceErrorType>
-ErrorInterface *ServiceError<ServiceErrorType>::AddCause(Error cause_err) noexcept {
+ErrorInterface *ServiceError<ServiceErrorType>::SetCause(Error cause_err) noexcept {
     cause_err_ = std::move(cause_err);
     return this;
 }
 
+inline std::string WrapInQuotes(const std::string &origin) {
+    return "\"" + origin + "\"";
+}
+
 template<typename ServiceErrorType>
 std::string ServiceError<ServiceErrorType>::ExplainInJSON() const noexcept {
-    return std::string();
+    std::string err = WrapInQuotes("error") + ":" + WrapInQuotes(error_name_);
+    if (!error_message_.empty()) {
+        err += "," + WrapInQuotes("message") + ":" + WrapInQuotes(error_message_);
+    }
+    if (!context_.empty()) {
+        err += "," + WrapInQuotes("context") + ":{";
+        auto i = 0;
+        for (const auto &kv : context_) {
+            err += (i > 0 ? ", " : "") + WrapInQuotes(kv.first) + ":" + WrapInQuotes(kv.second);
+            i++;
+        }
+        err += "}";
+    }
+    if (cause_err_ != nullptr) {
+        err += ","+ WrapInQuotes("cause")+":{"+cause_err_->ExplainInJSON()+"}";
+    }
+    return err;
 }
 
 template<typename ServiceErrorType>
diff --git a/common/cpp/include/asapo/logger/logger.h b/common/cpp/include/asapo/logger/logger.h
index 3f077d1be8969307a9c6692a7288f94ad9f18408..593f210311486882f514305d4593093c5a826a92 100644
--- a/common/cpp/include/asapo/logger/logger.h
+++ b/common/cpp/include/asapo/logger/logger.h
@@ -39,6 +39,10 @@ class AbstractLogger {
     virtual void Error(const std::string& text) const = 0;
     virtual void Debug(const std::string& text) const = 0;
     virtual void Warning(const std::string& text) const = 0;
+    virtual void Info(const asapo::Error& error) const = 0;
+    virtual void Error(const asapo::Error& error) const = 0;
+    virtual void Debug(const asapo::Error& error) const = 0;
+    virtual void Warning(const asapo::Error& error) const = 0;
     virtual void Info(const LogMessageWithFields& msg) const = 0;
     virtual void Error(const LogMessageWithFields& msg) const = 0;
     virtual void Debug(const LogMessageWithFields& msg) const = 0;
diff --git a/common/cpp/include/asapo/unittests/MockLogger.h b/common/cpp/include/asapo/unittests/MockLogger.h
index 0a8938ad392cae85b7d115ca2d61c048ee926c99..06b30a59d3fb15142490cd529934a69a55cd2969 100644
--- a/common/cpp/include/asapo/unittests/MockLogger.h
+++ b/common/cpp/include/asapo/unittests/MockLogger.h
@@ -10,6 +10,19 @@ namespace asapo {
 
 class MockLogger : public AbstractLogger {
   public:
+    void Info(const asapo::Error& msg) const override {
+        Info(msg->ExplainInJSON());
+    };
+    void Error(const asapo::Error& msg) const override {
+        Error(msg->ExplainInJSON());
+    };
+    void Debug(const asapo::Error& msg) const override {
+        Debug(msg->ExplainInJSON());
+    };
+    void Warning(const asapo::Error& msg) const override {
+        Warning(msg->ExplainInJSON());
+    };
+
     MOCK_CONST_METHOD1(Info, void(const std::string&));
     MOCK_CONST_METHOD1(Error, void(const std::string& ));
     MOCK_CONST_METHOD1(Debug, void(const std::string& ));
diff --git a/common/cpp/src/logger/spd_logger.cpp b/common/cpp/src/logger/spd_logger.cpp
index 4cc5c49b098abdbb2ef4321642055c64ca913943..21f9f6ec381949f793b39b5cac63d05ab3ceb1e5 100644
--- a/common/cpp/src/logger/spd_logger.cpp
+++ b/common/cpp/src/logger/spd_logger.cpp
@@ -141,4 +141,20 @@ void SpdLogger::Warning(const LogMessageWithFields& msg) const {
     Warning(msg.LogString());
 }
 
+void SpdLogger::Info(const asapo::Error& error) const {
+    Info(error->ExplainInJSON());
+}
+
+void SpdLogger::Error(const asapo::Error& error) const {
+    Error(error->ExplainInJSON());
+}
+
+void SpdLogger::Debug(const asapo::Error& error) const {
+    Debug(error->ExplainInJSON());
+}
+
+void SpdLogger::Warning(const asapo::Error& error) const {
+    Warning(error->ExplainInJSON());
+}
+
 }
diff --git a/common/cpp/src/logger/spd_logger.h b/common/cpp/src/logger/spd_logger.h
index e623b27dfe5c9ee5b41ab99bbaab5e4f8241469f..1c2485f95f8520012223e06b4609a28aeffd89fd 100644
--- a/common/cpp/src/logger/spd_logger.h
+++ b/common/cpp/src/logger/spd_logger.h
@@ -19,6 +19,10 @@ class SpdLogger : public AbstractLogger {
     void Error(const LogMessageWithFields& msg) const override;
     void Debug(const LogMessageWithFields& msg) const override;
     void Warning(const LogMessageWithFields& msg) const override;
+    void Info(const asapo::Error& error) const override;
+    void Error(const asapo::Error& error) const override;
+    void Debug(const asapo::Error& error) const override;
+    void Warning(const asapo::Error& error) const override;
 
     void EnableLocalLog(bool enable) override;
     void EnableRemoteLog(bool enable) override;
diff --git a/common/cpp/src/system_io/system_io.cpp b/common/cpp/src/system_io/system_io.cpp
index 55908b574a9aa377791a341667e288663d62049d..096315a6da632bdbb66b945f6b2d85c00fce6ffe 100644
--- a/common/cpp/src/system_io/system_io.cpp
+++ b/common/cpp/src/system_io/system_io.cpp
@@ -116,7 +116,7 @@ MessageData SystemIO::GetDataFromFile(const std::string& fname, uint64_t* fsize,
 
     Read(fd, data_array, (size_t)*fsize, err);
     if (*err != nullptr) {
-        (*err)->Append(fname + ", expected size: " + std::to_string(*fsize));
+        (*err)->AddContext("filename", fname)->AddContext("expected size", std::to_string(*fsize));
         Close(fd, nullptr);
         return nullptr;
     }
@@ -191,7 +191,7 @@ Error SystemIO::WriteDataToFile(const std::string& root_folder, const std::strin
 
     Write(fd, data, length, &err);
     if (err) {
-        err->Append(fname);
+        err->AddContext("filename", fname);
         return err;
     }
 
@@ -402,7 +402,7 @@ asapo::FileDescriptor asapo::SystemIO::Open(const std::string& filename,
     FileDescriptor fd = _open(filename.c_str(), flags);
     if (fd == -1) {
         *err = GetLastError();
-        (*err)->Append(filename);
+        (*err)->AddContext("filename", filename);
     } else {
         *err = nullptr;
     }
@@ -616,7 +616,7 @@ Error SystemIO::CreateDirectoryWithParents(const std::string& root_path, const s
         Error err;
         CreateNewDirectory(new_path, &err);
         if (err && err != IOErrorTemplates::kFileAlreadyExists) {
-            err->Append(new_path);
+            err->AddContext("path", new_path);
             return err;
         }
         if (iter != path.end()) {
diff --git a/common/cpp/src/system_io/system_io_linux.cpp b/common/cpp/src/system_io/system_io_linux.cpp
index 2c97e377fa03feb64a112bcf4abba10754f30c16..f4256bddba5fdecb3e9bb9869943d03c9c642d81 100644
--- a/common/cpp/src/system_io/system_io_linux.cpp
+++ b/common/cpp/src/system_io/system_io_linux.cpp
@@ -28,7 +28,7 @@ Error SystemIO::AddToEpool(SocketDescriptor sd) const {
     event.data.fd = sd;
     if((epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, sd, &event) == -1) && (errno != EEXIST)) {
         auto err =  GetLastError();
-        err->Append("add to epoll");
+        err->AddContext("where", "add to epoll");
         close(epoll_fd_);
         return err;
     }
@@ -43,7 +43,7 @@ Error SystemIO::CreateEpoolIfNeeded(SocketDescriptor master_socket) const {
     epoll_fd_ = epoll_create1(0);
     if(epoll_fd_ == kDisconnectedSocketDescriptor) {
         auto err = GetLastError();
-        err->Append("Create epoll");
+        err->AddContext("where", "create epoll");
         return err;
     }
     return AddToEpool(master_socket);
@@ -84,7 +84,7 @@ ListSocketDescriptors SystemIO::WaitSocketsActivity(SocketDescriptor master_sock
         }
         if (event_count < 0) {
             *err = GetLastError();
-            (*err)->Append("epoll wait");
+            (*err)->AddContext("where", "epoll wait");
             return {};
         }
 
diff --git a/common/cpp/src/system_io/system_io_linux_mac.cpp b/common/cpp/src/system_io/system_io_linux_mac.cpp
index 819c6d2d0660e3a6c54ab4ca02167eb7103cff04..bf913db61ea112794a174c49c1a167a829aaf52f 100644
--- a/common/cpp/src/system_io/system_io_linux_mac.cpp
+++ b/common/cpp/src/system_io/system_io_linux_mac.cpp
@@ -67,9 +67,8 @@ Error GetLastErrorFromErrno() {
     case EPIPE:
         return IOErrorTemplates::kBrokenPipe.Generate();
     default:
-        std::cout << "[IOErrorsFromErrno] Unknown error code: " << errno << std::endl;
         Error err = IOErrorTemplates::kUnknownIOError.Generate();
-        (*err).Append("Unknown error code: " + std::to_string(errno));
+        (*err).AddContext("Unknown error code: ", std::to_string(errno));
         return err;
     }
 }
@@ -123,7 +122,7 @@ MessageMeta GetMessageMeta(const string& name, Error* err) {
 
     auto t_stat = FileStat(name, err);
     if (*err != nullptr) {
-        (*err)->Append(name);
+        (*err)->AddContext("filename", name);
         return MessageMeta{};
     }
 
@@ -158,7 +157,7 @@ void SystemIO::GetSubDirectoriesRecursively(const std::string& path, SubDirList*
     auto dir = opendir((path).c_str());
     if (dir == nullptr) {
         *err = GetLastError();
-        (*err)->Append(path);
+        (*err)->AddContext("path", path);
         return;
     }
 
@@ -184,7 +183,7 @@ void SystemIO::CollectMessageMetarmationRecursively(const std::string& path,
     auto dir = opendir((path).c_str());
     if (dir == nullptr) {
         *err = GetLastError();
-        (*err)->Append(path);
+        (*err)->AddContext("path", path);
         return;
     }
 
diff --git a/common/cpp/src/system_io/system_io_windows.cpp b/common/cpp/src/system_io/system_io_windows.cpp
index 22b9c9d4315b5e7b764643230a331c200032fc05..282cf55238b5ba1a03de3c89a221d53aab722217 100644
--- a/common/cpp/src/system_io/system_io_windows.cpp
+++ b/common/cpp/src/system_io/system_io_windows.cpp
@@ -66,7 +66,7 @@ Error IOErrorFromGetLastError() {
     default:
         std::cout << "[IOErrorFromGetLastError] Unknown error code: " << last_error << std::endl;
         Error err = IOErrorTemplates::kUnknownIOError.Generate();
-        (*err).Append("Unknown error code: " + std::to_string(last_error));
+        (*err).AddContext("Unknown error code", std::to_string(last_error));
         return err;
     }
 }
@@ -151,7 +151,7 @@ MessageMeta SystemIO::GetMessageMeta(const std::string& name, Error* err) const
     auto hFind = FindFirstFile(name.c_str(), &f);
     if (hFind == INVALID_HANDLE_VALUE) {
         *err = IOErrorFromGetLastError();
-        (*err)->Append(name);
+        (*err)->AddContext("filename", name);
         return {};
     }
     FindClose(hFind);
@@ -179,7 +179,7 @@ void SystemIO::GetSubDirectoriesRecursively(const std::string& path, SubDirList*
     HANDLE handle = FindFirstFile((path + "\\*.*").c_str(), &find_data);
     if (handle == INVALID_HANDLE_VALUE) {
         *err = IOErrorFromGetLastError();
-        (*err)->Append(path);
+        (*err)->AddContext("path", path);
         return;
     }
 
@@ -208,7 +208,7 @@ void SystemIO::CollectMessageMetarmationRecursively(const std::string& path,
     HANDLE handle = FindFirstFile((path + "\\*.*").c_str(), &find_data);
     if (handle == INVALID_HANDLE_VALUE) {
         *err = IOErrorFromGetLastError();
-        (*err)->Append(path);
+        (*err)->AddContext("path", path);
         return;
     }
 
diff --git a/common/cpp/unittests/common/test_error.cpp b/common/cpp/unittests/common/test_error.cpp
index 8f1ffd34d70a5be940eb12871dfdd7c3a411f963..c588ea0526be16f5977367ee9e5fdb36cdaf3cee 100644
--- a/common/cpp/unittests/common/test_error.cpp
+++ b/common/cpp/unittests/common/test_error.cpp
@@ -17,7 +17,6 @@ TEST(ErrorTemplate, EqCheck) {
     ASSERT_TRUE(asapo::GeneralErrorTemplates::kEndOfFile == error);
 }
 
-
 TEST(ErrorTemplate, NeCheck) {
     Error error = asapo::GeneralErrorTemplates::kEndOfFile.Generate();
     ASSERT_FALSE(asapo::GeneralErrorTemplates::kMemoryAllocationError == error);
@@ -28,9 +27,50 @@ TEST(ErrorTemplate, Explain) {
     ASSERT_THAT(error->Explain(), HasSubstr("test"));
 }
 
-TEST(ErrorTemplate, Append) {
+TEST(ErrorTemplate, Context) {
     Error error = asapo::GeneralErrorTemplates::kEndOfFile.Generate("test");
-    ASSERT_THAT(error->Explain(), HasSubstr("test"));
+    error->AddContext("key", "value");
+    error->AddContext("key2", "value2");
+
+    ASSERT_THAT(error->Explain(), AllOf(HasSubstr("test"),
+                                        HasSubstr("context"),
+                                        HasSubstr("key:value"),
+                                        HasSubstr("key2:value2")
+                                       ));
+}
+
+TEST(ErrorTemplate, Cause) {
+    Error error = asapo::GeneralErrorTemplates::kEndOfFile.Generate("test");
+    Error error_c = asapo::GeneralErrorTemplates::kMemoryAllocationError.Generate("cause_test");
+    Error error_c1 = asapo::GeneralErrorTemplates::kSimpleError.Generate("simple error");
+    error->AddContext("key", "value");
+    error_c->AddContext("key2", "value2");
+    error_c->SetCause(std::move(error_c1));
+    error->SetCause(std::move(error_c));
+    ASSERT_THAT(error->Explain(), AllOf(HasSubstr("test"),
+                                        HasSubstr("caused"),
+                                        HasSubstr("key:value"),
+                                        HasSubstr("key:value"),
+                                        HasSubstr("key2:value2")
+                                       ));
+    ASSERT_THAT(error->ExplainPretty(), AllOf(HasSubstr("test"),
+                                              HasSubstr("caused"),
+                                              HasSubstr("key:value"),
+                                              HasSubstr("key:value"),
+                                              HasSubstr("key2:value2")
+                                             ));
 }
 
+TEST(ErrorTemplate, Json) {
+    Error error = asapo::GeneralErrorTemplates::kEndOfFile.Generate("test");
+    Error error_c = asapo::GeneralErrorTemplates::kMemoryAllocationError.Generate("cause_test");
+    error->AddContext("key", "value");
+    error->SetCause(std::move(error_c));
+    auto expected_string =
+        R"("error":"end of file","message":"test","context":{"key":"value"},"cause":{"error":"memory allocation","message":"cause_test"})";
+    ASSERT_THAT(error->ExplainInJSON(),  Eq(expected_string));
+}
+
+
+
 }
diff --git a/common/cpp/unittests/logger/test_logger.cpp b/common/cpp/unittests/logger/test_logger.cpp
index ed67359e1479f6d65fda1b7dc1d7a8a1cb4e5382..f5346e0261619c032385d456e044a8e36fa366a6 100644
--- a/common/cpp/unittests/logger/test_logger.cpp
+++ b/common/cpp/unittests/logger/test_logger.cpp
@@ -70,6 +70,7 @@ class LoggerTests : public Test {
     asapo::SpdLogger logger{"test", "test_uri"};
     spdlog::details::log_msg msg;
     spdlog::details::log_msg msg_json;
+    spdlog::details::log_msg msg_error;
 
     std::string test_string{"Hello\""};
     std::string test_string_json{R"("Hello":"test","int":1,"double":123.234)"};
@@ -77,6 +78,7 @@ class LoggerTests : public Test {
     void SetUp() override {
         msg.raw << R"("message":"Hello\"")";
         msg_json.raw << R"("Hello":"test","int":1,"double":123.234)";
+        msg_error.raw << R"("error":"unnamed error","message":"err")";
         log.reset(new spdlog::logger("mylogger", mock_sink));
         logger.log__ = std::move(log);
     }
@@ -114,6 +116,18 @@ TEST_F(LoggerTests, InfoJson) {
     logger.Info(test_string_json);
 }
 
+
+TEST_F(LoggerTests, InfoError) {
+    msg_error.level = spdlog::level::info;
+    logger.SetLogLevel(LogLevel::Info);
+    EXPECT_CALL(*mock_sink, _sink_it(CompareMsg(&msg_error)));
+
+    auto err = asapo::GeneralErrorTemplates::kSimpleError.Generate("err");
+
+    logger.Info(err);
+}
+
+
 TEST_F(LoggerTests, InfoMessage) {
     msg_json.level = spdlog::level::info;
 
diff --git a/consumer/api/cpp/src/consumer_impl.cpp b/consumer/api/cpp/src/consumer_impl.cpp
index 738434f7b647b1ae63d3dd166d9216fc377f4f0e..0fda0f43709ff1e1d72915856043e11244415f49 100644
--- a/consumer/api/cpp/src/consumer_impl.cpp
+++ b/consumer/api/cpp/src/consumer_impl.cpp
@@ -105,26 +105,26 @@ Error ConsumerErrorFromHttpCode(const RequestOutput* response, const HttpCode& c
 }
 Error ConsumerErrorFromServerError(const Error& server_err) {
     if (server_err == HttpErrorTemplates::kTransferError) {
-        return ConsumerErrorTemplates::kInterruptedTransaction.Generate(server_err->Explain());
+        return ConsumerErrorTemplates::kInterruptedTransaction.Generate();
     } else {
-        return ConsumerErrorTemplates::kUnavailableService.Generate(server_err->Explain());
+        return ConsumerErrorTemplates::kUnavailableService.Generate();
     }
 }
 
 Error ProcessRequestResponce(const RequestInfo& request,
-                             const Error& server_err,
+                             Error server_err,
                              const RequestOutput* response,
                              const HttpCode& code) {
     Error err;
     if (server_err != nullptr) {
         err =  ConsumerErrorFromServerError(server_err);
+        err->SetCause(std::move(server_err));
     } else {
         err =  ConsumerErrorFromHttpCode(response, code);
     }
 
     if (err != nullptr) {
-        std::string prefix = "Error processing request " + request.host + request.api;
-        err->Prepend(prefix);
+        err->AddContext("host", request.host)->AddContext("api", "request.api");
     }
     return err;
 
@@ -202,7 +202,7 @@ Error ConsumerImpl::ProcessRequest(RequestOutput* response, const RequestInfo& r
     if (err && service_uri) {
         service_uri->clear();
     }
-    return ProcessRequestResponce(request, err, response, code);
+    return ProcessRequestResponce(request, std::move(err), response, code);
 }
 
 RequestInfo ConsumerImpl::GetDiscoveryRequest(const std::string& service_name) const {
diff --git a/consumer/api/cpp/src/consumer_impl.h b/consumer/api/cpp/src/consumer_impl.h
index e8228e60aacdb135a0bb560266269fe50578020c..d25f4327a757d588c8027f91bef48b2f072f999f 100644
--- a/consumer/api/cpp/src/consumer_impl.h
+++ b/consumer/api/cpp/src/consumer_impl.h
@@ -47,7 +47,7 @@ struct RequestOutput {
     }
 };
 
-Error ProcessRequestResponce(const RequestInfo& request, const Error& server_err, const RequestOutput* response,
+Error ProcessRequestResponce(const RequestInfo& request, Error server_err, const RequestOutput* response,
                              const HttpCode& code);
 Error ConsumerErrorFromNoDataResponse(const std::string& response);
 Error ConsumerErrorFromPartialDataResponse(const std::string& response);
diff --git a/producer/api/cpp/src/request_handler_tcp.cpp b/producer/api/cpp/src/request_handler_tcp.cpp
index a2f2409e1721b39d82ca9fdfdf6fe1f2dc539071..9595e3146b790beae689cb043978678cea7285db 100644
--- a/producer/api/cpp/src/request_handler_tcp.cpp
+++ b/producer/api/cpp/src/request_handler_tcp.cpp
@@ -93,22 +93,22 @@ Error RequestHandlerTcp::ReceiveResponse(std::string* response) {
     switch (sendDataResponse.error_code) {
     case kNetAuthorizationError : {
         auto res_err = ProducerErrorTemplates::kWrongInput.Generate();
-        res_err->Append(sendDataResponse.message);
+        res_err->AddContext("response", sendDataResponse.message);
         return res_err;
     }
     case kNetErrorNotSupported : {
         auto res_err = ProducerErrorTemplates::kUnsupportedClient.Generate();
-        res_err->Append(sendDataResponse.message);
+        res_err->AddContext("response", sendDataResponse.message);
         return res_err;
     }
     case kNetErrorWrongRequest : {
         auto res_err = ProducerErrorTemplates::kWrongInput.Generate();
-        res_err->Append(sendDataResponse.message);
+        res_err->AddContext("response", sendDataResponse.message);
         return res_err;
     }
     case kNetErrorWarning: {
         auto res_err = ProducerErrorTemplates::kServerWarning.Generate();
-        res_err->Append(sendDataResponse.message);
+        res_err->AddContext("response", sendDataResponse.message);
         return res_err;
     }
     case kNetErrorReauthorize: {
@@ -122,7 +122,7 @@ Error RequestHandlerTcp::ReceiveResponse(std::string* response) {
         return nullptr;
     default:
         auto res_err = ProducerErrorTemplates::kInternalServerError.Generate();
-        res_err->Append(sendDataResponse.message);
+        res_err->AddContext("response", sendDataResponse.message);
         return res_err;
     }
 }
diff --git a/receiver/src/request.cpp b/receiver/src/request.cpp
index b815a33e675fe340681683102e395d61a39898de..0c4ed721b105dc68bf7a93c044ecc8b71150d212 100644
--- a/receiver/src/request.cpp
+++ b/receiver/src/request.cpp
@@ -18,8 +18,7 @@ Error Request::PrepareDataBufferAndLockIfNeeded() {
         try {
             data_buffer_.reset(new uint8_t[(size_t)request_header_.data_size]);
         } catch(std::exception& e) {
-            auto err = GeneralErrorTemplates::kMemoryAllocationError.Generate();
-            err->Append(e.what());
+            auto err = GeneralErrorTemplates::kMemoryAllocationError.Generate(e.what());
             return err;
         }
     } else {