diff --git a/src/call.cpp b/src/call.cpp
index de068038d242671007bd1b0bd420813c9d26141f..47cedd596ab97e0b84837907e5a0f336a46dc51c 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -124,10 +124,13 @@ Call::validTransition(CallState newState)
 bool
 Call::setState(CallState state)
 {
+
     std::lock_guard<std::mutex> lock(callMutex_);
     if (not validTransition(state)) {
-        assert((int)callState_ < enum_class_size<CallState>() && (int)state < enum_class_size<CallState>());
-        //RING_ERR("Invalid call state transition from %s to %s", states[callState_], states[state]);
+        assert((int)callState_ < enum_class_size<CallState>()
+               && (int)state < enum_class_size<CallState>());
+        RING_ERR("Invalid attempted call state transition from %d to %d",
+                 callState_, state);
         return false;
     }
 
diff --git a/src/call.h b/src/call.h
index 88f90323b6a37aab9eca734136b7a99045a62cd6..767950a243e45e7e497215cd9d899a47aafb685d 100644
--- a/src/call.h
+++ b/src/call.h
@@ -271,13 +271,13 @@ class Call : public Recordable, public std::enable_shared_from_this<Call> {
          * Put a call on hold
          * @return bool True on success
          */
-        virtual void onhold() = 0;
+        virtual bool onhold() = 0;
 
         /**
          * Resume a call from hold state
          * @return bool True on success
          */
-        virtual void offhold() = 0;
+        virtual bool offhold() = 0;
 
         /**
          * mute/unmute a media of a call
diff --git a/src/iax/iaxcall.cpp b/src/iax/iaxcall.cpp
index 7332f36e8f4cbe49dffe9968c664a937cfd672fc..38fb846ba40a6b8e712add3c1e4e4416cf4863b2 100644
--- a/src/iax/iaxcall.cpp
+++ b/src/iax/iaxcall.cpp
@@ -194,7 +194,7 @@ IAXCall::attendedTransfer(const std::string& /*targetID*/)
     return false; // TODO
 }
 
-void
+bool
 IAXCall::onhold()
 {
     Manager::instance().getRingBufferPool().unBindAll(getCallId());
@@ -204,12 +204,14 @@ IAXCall::onhold()
         iax_quelch_moh(session, true);
     }
 
-    setState(Call::CallState::HOLD);
+    return setState(Call::CallState::HOLD);
 }
 
-void
+bool
 IAXCall::offhold()
 {
+    bool success = false;
+
     Manager::instance().addStream(*this);
 
     {
@@ -217,9 +219,10 @@ IAXCall::offhold()
         iax_unquelch(session);
     }
 
-    setState(Call::CallState::ACTIVE);
+    if (success = setState(Call::CallState::ACTIVE))
+        Manager::instance().startAudioDriverStream();
 
-    Manager::instance().startAudioDriverStream();
+    return success;
 }
 
 void
diff --git a/src/iax/iaxcall.h b/src/iax/iaxcall.h
index a84599aef8a2d72e87056a16711fe9e22e5d3daa..1ace687369333dd03136a6c375d18b0a86ef3b3c 100644
--- a/src/iax/iaxcall.h
+++ b/src/iax/iaxcall.h
@@ -127,9 +127,9 @@ class IAXCall : public Call
 
         bool attendedTransfer(const std::string& to);
 
-        void onhold();
+        bool onhold();
 
-        void offhold();
+        bool offhold();
 
         //TODO: implement mute for IAX
         void muteMedia(const std::string& mediaType, bool isMuted) {}
diff --git a/src/manager.cpp b/src/manager.cpp
index 802a07c24727c3e5b58fd70058b723240b6cbc5b..d686c6eeffd15a4091692a45297f8435720f1a5f 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -628,26 +628,29 @@ Manager::onHoldCall(const std::string& callId)
 
     if (auto call = getCallFromCallID(callId)) {
         try {
-            call->onhold();
-            removeStream(*call); // Unbind calls in main buffer
+            if (result = call->onhold())
+                removeStream(*call); // Unbind calls in main buffer
         } catch (const VoipLinkException &e) {
             RING_ERR("%s", e.what());
             result = false;
         }
+
     } else {
         RING_DBG("CallID %s doesn't exist in call onHold", callId.c_str());
         return false;
     }
 
-    // Remove call from teh queue if it was still there
-    removeWaitingCall(callId);
+    if (result) {
+        // Remove call from the queue if it was still there
+        removeWaitingCall(callId);
 
-    // keeps current call id if the action is not holding this call or a new outgoing call
-    // this could happen in case of a conference
-    if (current_call_id == callId)
-        unsetCurrentCall();
+        // keeps current call id if the action is not holding this call
+        // or a new outgoing call. This could happen in case of a conference
+        if (current_call_id == callId)
+            unsetCurrentCall();
 
-    emitSignal<DRing::CallSignal::StateChange>(callId, "HOLD", 0);
+        emitSignal<DRing::CallSignal::StateChange>(callId, "HOLD", 0);
+    }
 
     return result;
 }
diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp
index 4f099f6a3e8f6446c136b02f44d784dabd62a1a7..efcd8dcb53a1cea9a354335d18ae7d870f389c0d 100644
--- a/src/sip/sipcall.cpp
+++ b/src/sip/sipcall.cpp
@@ -585,11 +585,11 @@ SIPCall::attendedTransfer(const std::string& to)
     return transferCommon(&dst);
 }
 
-void
+bool
 SIPCall::onhold()
 {
     if (not setState(CallState::HOLD))
-        return;
+        return false;
 
     stopAllMedia();
 
@@ -597,30 +597,35 @@ SIPCall::onhold()
         if (SIPSessionReinvite() != PJ_SUCCESS)
             RING_WARN("Reinvite failed");
     }
+
+    return true;
 }
 
-void
+bool
 SIPCall::offhold()
 {
+    bool success = false;
     auto& account = getSIPAccount();
 
     try {
         if (account.isStunEnabled())
-            internalOffHold([&] { updateSDPFromSTUN(); });
+            success = internalOffHold([&] { updateSDPFromSTUN(); });
         else
-            internalOffHold([] {});
+            success = internalOffHold([] {});
 
     } catch (const SdpException &e) {
         RING_ERR("%s", e.what());
         throw VoipLinkException("SDP issue in offhold");
     }
+
+    return success;
 }
 
-void
+bool
 SIPCall::internalOffHold(const std::function<void()>& sdp_cb)
 {
     if (not setState(CallState::ACTIVE))
-        return;
+        return false;
 
     sdp_cb();
 
@@ -628,8 +633,11 @@ SIPCall::internalOffHold(const std::function<void()>& sdp_cb)
         if (SIPSessionReinvite() != PJ_SUCCESS) {
             RING_WARN("Reinvite failed, resuming hold");
             onhold();
+            return false;
         }
     }
+
+    return true;
 }
 
 void
diff --git a/src/sip/sipcall.h b/src/sip/sipcall.h
index 46b05b29205abc8677b8df7946c888157e7acf52..06ac8cbf3c5791fcdfa40243a834f26d8a94b805 100644
--- a/src/sip/sipcall.h
+++ b/src/sip/sipcall.h
@@ -152,9 +152,9 @@ class SIPCall : public Call
 
         bool attendedTransfer(const std::string& to);
 
-        void onhold();
+        bool onhold();
 
-        void offhold();
+        bool offhold();
 
         void switchInput(const std::string& resource);
 
@@ -221,7 +221,7 @@ class SIPCall : public Call
          */
         bool transferCommon(pj_str_t *dst);
 
-        void internalOffHold(const std::function<void()> &SDPUpdateFunc);
+        bool internalOffHold(const std::function<void()> &SDPUpdateFunc);
 
         int SIPSessionReinvite();