diff --git a/src/core/hle/service/nfc/common/amiibo_crypto.cpp b/src/core/hle/service/nfc/common/amiibo_crypto.cpp
index bc232c334d..9556e91936 100644
--- a/src/core/hle/service/nfc/common/amiibo_crypto.cpp
+++ b/src/core/hle/service/nfc/common/amiibo_crypto.cpp
@@ -180,7 +180,7 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
 }
 
 void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key,
-                const std::vector<u8>& seed) {
+                std::span<const u8> seed) {
     // Initialize context
     ctx.used = false;
     ctx.counter = 0;
diff --git a/src/core/hle/service/nfc/common/amiibo_crypto.h b/src/core/hle/service/nfc/common/amiibo_crypto.h
index 6a3e0841eb..2cc0e4d519 100644
--- a/src/core/hle/service/nfc/common/amiibo_crypto.h
+++ b/src/core/hle/service/nfc/common/amiibo_crypto.h
@@ -75,7 +75,7 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
 
 // Initializes mbedtls context
 void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key,
-                const std::vector<u8>& seed);
+                std::span<const u8> seed);
 
 // Feeds data to mbedtls context to generate the derived key
 void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& output);
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp
index 2d633b03fa..49446bc423 100644
--- a/src/core/hle/service/nfc/common/device.cpp
+++ b/src/core/hle/service/nfc/common/device.cpp
@@ -34,8 +34,6 @@
 #include "core/hle/service/nfc/mifare_result.h"
 #include "core/hle/service/nfc/nfc_result.h"
 #include "core/hle/service/time/time_manager.h"
-#include "core/hle/service/time/time_zone_content_manager.h"
-#include "core/hle/service/time/time_zone_types.h"
 
 namespace Service::NFC {
 NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_,
@@ -1486,6 +1484,7 @@ DeviceState NfcDevice::GetCurrentState() const {
 }
 
 Result NfcDevice::GetNpadId(Core::HID::NpadIdType& out_npad_id) const {
+    // TODO: This should get the npad id from nn::hid::system::GetXcdHandleForNpadWithNfc
     out_npad_id = npad_id;
     return ResultSuccess;
 }
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp
index 562f3a28ea..a71d26157f 100644
--- a/src/core/hle/service/nfc/common/device_manager.cpp
+++ b/src/core/hle/service/nfc/common/device_manager.cpp
@@ -1,6 +1,8 @@
 // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-3.0-or-later
 
+#include <algorithm>
+
 #include "common/logging/log.h"
 #include "core/core.h"
 #include "core/hid/hid_types.h"
@@ -10,6 +12,7 @@
 #include "core/hle/service/nfc/common/device_manager.h"
 #include "core/hle/service/nfc/nfc_result.h"
 #include "core/hle/service/time/clock_types.h"
+#include "core/hle/service/time/time_manager.h"
 
 namespace Service::NFC {
 
@@ -51,22 +54,53 @@ Result DeviceManager::Finalize() {
     return ResultSuccess;
 }
 
-Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices,
-                                  std::size_t max_allowed_devices) const {
+Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices,
+                                  bool skip_fatal_errors) const {
+    std::scoped_lock lock{mutex};
+    if (max_allowed_devices < 1) {
+        return ResultInvalidArgument;
+    }
+
+    Result result = IsNfcParameterSet();
+    if (result.IsError()) {
+        return result;
+    }
+
+    result = IsNfcEnabled();
+    if (result.IsError()) {
+        return result;
+    }
+
+    result = IsNfcInitialized();
+    if (result.IsError()) {
+        return result;
+    }
+
     for (auto& device : devices) {
         if (nfp_devices.size() >= max_allowed_devices) {
             continue;
         }
-        if (device->GetCurrentState() != DeviceState::Unavailable) {
-            nfp_devices.push_back(device->GetHandle());
+        if (skip_fatal_errors) {
+            constexpr u64 MinimumRecoveryTime = 60;
+            auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()};
+            const u64 elapsed_time = standard_steady_clock.GetCurrentTimePoint(system).time_point -
+                                     time_since_last_error;
+
+            if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) {
+                continue;
+            }
         }
+        if (device->GetCurrentState() == DeviceState::Unavailable) {
+            continue;
+        }
+        nfp_devices.push_back(device->GetHandle());
     }
 
     if (nfp_devices.empty()) {
         return ResultDeviceNotFound;
     }
 
-    return ResultSuccess;
+    return result;
 }
 
 DeviceState DeviceManager::GetDeviceState(u64 device_handle) const {
@@ -79,10 +113,10 @@ DeviceState DeviceManager::GetDeviceState(u64 device_handle) const {
         return device->GetCurrentState();
     }
 
-    return DeviceState::Unavailable;
+    return DeviceState::Finalized;
 }
 
-Result DeviceManager::GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) const {
+Result DeviceManager::GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -128,7 +162,7 @@ Result DeviceManager::StopDetection(u64 device_handle) {
     return result;
 }
 
-Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const {
+Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -142,24 +176,46 @@ Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const {
     return result;
 }
 
-Kernel::KReadableEvent& DeviceManager::AttachActivateEvent(u64 device_handle) const {
-    std::scoped_lock lock{mutex};
-
+Result DeviceManager::AttachActivateEvent(Kernel::KReadableEvent** out_event,
+                                          u64 device_handle) const {
+    std::vector<u64> nfp_devices;
     std::shared_ptr<NfcDevice> device = nullptr;
-    GetDeviceFromHandle(device_handle, device, false);
+    Result result = ListDevices(nfp_devices, 9, false);
 
-    // TODO: Return proper error code on failure
-    return device->GetActivateEvent();
+    if (result.IsSuccess()) {
+        result = CheckHandleOnList(device_handle, nfp_devices);
+    }
+
+    if (result.IsSuccess()) {
+        result = GetDeviceFromHandle(device_handle, device, false);
+    }
+
+    if (result.IsSuccess()) {
+        *out_event = &device->GetActivateEvent();
+    }
+
+    return result;
 }
 
-Kernel::KReadableEvent& DeviceManager::AttachDeactivateEvent(u64 device_handle) const {
-    std::scoped_lock lock{mutex};
-
+Result DeviceManager::AttachDeactivateEvent(Kernel::KReadableEvent** out_event,
+                                            u64 device_handle) const {
+    std::vector<u64> nfp_devices;
     std::shared_ptr<NfcDevice> device = nullptr;
-    GetDeviceFromHandle(device_handle, device, false);
+    Result result = ListDevices(nfp_devices, 9, false);
 
-    // TODO: Return proper error code on failure
-    return device->GetDeactivateEvent();
+    if (result.IsSuccess()) {
+        result = CheckHandleOnList(device_handle, nfp_devices);
+    }
+
+    if (result.IsSuccess()) {
+        result = GetDeviceFromHandle(device_handle, device, false);
+    }
+
+    if (result.IsSuccess()) {
+        *out_event = &device->GetDeactivateEvent();
+    }
+
+    return result;
 }
 
 Result DeviceManager::ReadMifare(u64 device_handle,
@@ -253,7 +309,7 @@ Result DeviceManager::OpenApplicationArea(u64 device_handle, u32 access_id) {
     return result;
 }
 
-Result DeviceManager::GetApplicationArea(u64 device_handle, std::span<u8> data) const {
+Result DeviceManager::GetApplicationArea(u64 device_handle, std::span<u8> data) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -324,7 +380,7 @@ Result DeviceManager::CreateApplicationArea(u64 device_handle, u32 access_id,
     return result;
 }
 
-Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const {
+Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -338,7 +394,7 @@ Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& regi
     return result;
 }
 
-Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const {
+Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -352,7 +408,7 @@ Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_i
     return result;
 }
 
-Result DeviceManager::GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const {
+Result DeviceManager::GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -399,7 +455,7 @@ Result DeviceManager::Format(u64 device_handle) {
     return result;
 }
 
-Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const {
+Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -414,7 +470,7 @@ Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info
 }
 
 Result DeviceManager::GetRegisterInfoPrivate(u64 device_handle,
-                                             NFP::RegisterInfoPrivate& register_info) const {
+                                             NFP::RegisterInfoPrivate& register_info) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -471,7 +527,7 @@ Result DeviceManager::DeleteApplicationArea(u64 device_handle) {
     return result;
 }
 
-Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_application_area) const {
+Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_application_area) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -485,7 +541,7 @@ Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_applica
     return result;
 }
 
-Result DeviceManager::GetAll(u64 device_handle, NFP::NfpData& nfp_data) const {
+Result DeviceManager::GetAll(u64 device_handle, NFP::NfpData& nfp_data) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -541,7 +597,7 @@ Result DeviceManager::BreakTag(u64 device_handle, NFP::BreakType break_type) {
     return result;
 }
 
-Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) const {
+Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) {
     std::scoped_lock lock{mutex};
 
     std::shared_ptr<NfcDevice> device = nullptr;
@@ -593,6 +649,19 @@ Result DeviceManager::WriteNtf(u64 device_handle, NFP::WriteType, std::span<cons
     return result;
 }
 
+Result DeviceManager::CheckHandleOnList(u64 device_handle,
+                                        const std::span<const u64> device_list) const {
+    if (device_list.size() < 1) {
+        return ResultDeviceNotFound;
+    }
+
+    if (std::find(device_list.begin(), device_list.end(), device_handle) != device_list.end()) {
+        return ResultSuccess;
+    }
+
+    return ResultDeviceNotFound;
+}
+
 Result DeviceManager::GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& nfc_device,
                                           bool check_state) const {
     if (check_state) {
@@ -647,7 +716,7 @@ Result DeviceManager::GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& de
 }
 
 Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device,
-                                         Result operation_result) const {
+                                         Result operation_result) {
     if (operation_result.IsSuccess()) {
         return operation_result;
     }
@@ -669,6 +738,12 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device,
         return device_state;
     }
 
+    if (operation_result == ResultUnknown112 || operation_result == ResultUnknown114 ||
+        operation_result == ResultUnknown115) {
+        auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()};
+        time_since_last_error = standard_steady_clock.GetCurrentTimePoint(system).time_point;
+    }
+
     return operation_result;
 }
 
diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h
index c61ba0cf32..c9f038e329 100644
--- a/src/core/hle/service/nfc/common/device_manager.h
+++ b/src/core/hle/service/nfc/common/device_manager.h
@@ -27,15 +27,16 @@ public:
     // Nfc device manager
     Result Initialize();
     Result Finalize();
-    Result ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices) const;
+    Result ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices,
+                       bool skip_fatal_errors) const;
     DeviceState GetDeviceState(u64 device_handle) const;
-    Result GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) const;
+    Result GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id);
     Kernel::KReadableEvent& AttachAvailabilityChangeEvent() const;
     Result StartDetection(u64 device_handle, NfcProtocol tag_protocol);
     Result StopDetection(u64 device_handle);
-    Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info) const;
-    Kernel::KReadableEvent& AttachActivateEvent(u64 device_handle) const;
-    Kernel::KReadableEvent& AttachDeactivateEvent(u64 device_handle) const;
+    Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info);
+    Result AttachActivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const;
+    Result AttachDeactivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const;
     Result ReadMifare(u64 device_handle,
                       const std::span<const MifareReadBlockParameter> read_parameters,
                       std::span<MifareReadBlockData> read_data);
@@ -48,28 +49,28 @@ public:
     Result Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target);
     Result Unmount(u64 device_handle);
     Result OpenApplicationArea(u64 device_handle, u32 access_id);
-    Result GetApplicationArea(u64 device_handle, std::span<u8> data) const;
+    Result GetApplicationArea(u64 device_handle, std::span<u8> data);
     Result SetApplicationArea(u64 device_handle, std::span<const u8> data);
     Result Flush(u64 device_handle);
     Result Restore(u64 device_handle);
     Result CreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data);
-    Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const;
-    Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const;
-    Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const;
+    Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info);
+    Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info);
+    Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info);
     u32 GetApplicationAreaSize() const;
     Result RecreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data);
     Result Format(u64 device_handle);
-    Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const;
-    Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info) const;
+    Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info);
+    Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info);
     Result SetRegisterInfoPrivate(u64 device_handle, const NFP::RegisterInfoPrivate& register_info);
     Result DeleteRegisterInfo(u64 device_handle);
     Result DeleteApplicationArea(u64 device_handle);
-    Result ExistsApplicationArea(u64 device_handle, bool& has_application_area) const;
-    Result GetAll(u64 device_handle, NFP::NfpData& nfp_data) const;
+    Result ExistsApplicationArea(u64 device_handle, bool& has_application_area);
+    Result GetAll(u64 device_handle, NFP::NfpData& nfp_data);
     Result SetAll(u64 device_handle, const NFP::NfpData& nfp_data);
     Result FlushDebug(u64 device_handle);
     Result BreakTag(u64 device_handle, NFP::BreakType break_type);
-    Result ReadBackupData(u64 device_handle, std::span<u8> data) const;
+    Result ReadBackupData(u64 device_handle, std::span<u8> data);
     Result WriteBackupData(u64 device_handle, std::span<const u8> data);
     Result WriteNtf(u64 device_handle, NFP::WriteType, std::span<const u8> data);
 
@@ -78,17 +79,20 @@ private:
     Result IsNfcParameterSet() const;
     Result IsNfcInitialized() const;
 
+    Result CheckHandleOnList(u64 device_handle, std::span<const u64> device_list) const;
+
     Result GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& device,
                                bool check_state) const;
 
     Result GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& device) const;
-    Result VerifyDeviceResult(std::shared_ptr<NfcDevice> device, Result operation_result) const;
+    Result VerifyDeviceResult(std::shared_ptr<NfcDevice> device, Result operation_result);
     Result CheckDeviceState(std::shared_ptr<NfcDevice> device) const;
 
     std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle);
     const std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle) const;
 
     bool is_initialized = false;
+    u64 time_since_last_error = 0;
     mutable std::mutex mutex;
     std::array<std::shared_ptr<NfcDevice>, 10> devices{};
 
diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp
index e7ca7582ed..179c7ba2c4 100644
--- a/src/core/hle/service/nfc/nfc_interface.cpp
+++ b/src/core/hle/service/nfc/nfc_interface.cpp
@@ -79,7 +79,7 @@ void NfcInterface::ListDevices(HLERequestContext& ctx) {
     const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>();
     LOG_DEBUG(Service_NFC, "called");
 
-    auto result = GetManager()->ListDevices(nfp_devices, max_allowed_devices);
+    auto result = GetManager()->ListDevices(nfp_devices, max_allowed_devices, true);
     result = TranslateResultToServiceError(result);
 
     if (result.IsError()) {
@@ -190,9 +190,13 @@ void NfcInterface::AttachActivateEvent(HLERequestContext& ctx) {
     const auto device_handle{rp.Pop<u64>()};
     LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
 
+    Kernel::KReadableEvent* out_event = nullptr;
+    auto result = GetManager()->AttachActivateEvent(&out_event, device_handle);
+    result = TranslateResultToServiceError(result);
+
     IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(GetManager()->AttachActivateEvent(device_handle));
+    rb.Push(result);
+    rb.PushCopyObjects(out_event);
 }
 
 void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
@@ -200,9 +204,13 @@ void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
     const auto device_handle{rp.Pop<u64>()};
     LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
 
+    Kernel::KReadableEvent* out_event = nullptr;
+    auto result = GetManager()->AttachDeactivateEvent(&out_event, device_handle);
+    result = TranslateResultToServiceError(result);
+
     IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(GetManager()->AttachDeactivateEvent(device_handle));
+    rb.Push(result);
+    rb.PushCopyObjects(out_event);
 }
 
 void NfcInterface::ReadMifare(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/nfc/nfc_result.h b/src/core/hle/service/nfc/nfc_result.h
index 715c0e80c6..464b5fd69a 100644
--- a/src/core/hle/service/nfc/nfc_result.h
+++ b/src/core/hle/service/nfc/nfc_result.h
@@ -17,7 +17,10 @@ constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77);
 constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80);
 constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88);
 constexpr Result ResultTagRemoved(ErrorModule::NFC, 97);
+constexpr Result ResultUnknown112(ErrorModule::NFC, 112);
 constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113);
+constexpr Result ResultUnknown114(ErrorModule::NFC, 114);
+constexpr Result ResultUnknown115(ErrorModule::NFC, 115);
 constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120);
 constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128);
 constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136);