diff --git a/daemon/src/ice_transport.cpp b/daemon/src/ice_transport.cpp
index 2b83fba7f2004e0a5eaf1848f40e5bdb80004901..2020ed70d6ead75251f715228ba4d2269b31f209 100644
--- a/daemon/src/ice_transport.cpp
+++ b/daemon/src/ice_transport.cpp
@@ -472,18 +472,22 @@ IceTransport::selectUPnPIceCandidates()
          * add candidate with that port and public IP
          */
         IpAddr publicIP = upnp_->getExternalIP();
-        for(unsigned comp_id = 0; comp_id < component_count_; comp_id++) {
-            RING_DBG("UPnP : Opening port(s) for Ice comp %d and adding candidate with public IP.", comp_id);
-            std::vector<IpAddr> candidates = getLocalCandidatesAddr(comp_id);
-            for(IpAddr addr : candidates) {
-                uint16_t port = addr.getPort();
-                uint16_t port_used;
-                if (upnp_->addAnyMapping(port, upnp::PortType::UDP, true, &port_used)) {
-                    publicIP.setPort(port_used);
-                    addCandidate(comp_id, publicIP);
-                } else
-                    RING_WARN("UPnP : Could not create a port mapping for the ICE candidae.");
+        if (publicIP) {
+            for(unsigned comp_id = 0; comp_id < component_count_; comp_id++) {
+                RING_DBG("UPnP : Opening port(s) for Ice comp %d and adding candidate with public IP.", comp_id);
+                std::vector<IpAddr> candidates = getLocalCandidatesAddr(comp_id);
+                for(IpAddr addr : candidates) {
+                    uint16_t port = addr.getPort();
+                    uint16_t port_used;
+                    if (upnp_->addAnyMapping(port, upnp::PortType::UDP, true, &port_used)) {
+                        publicIP.setPort(port_used);
+                        addCandidate(comp_id, publicIP);
+                    } else
+                        RING_WARN("UPnP : Could not create a port mapping for the ICE candidae.");
+                }
             }
+        } else {
+            RING_WARN("UPnP : Could not determine public IP for ICE candidates.");
         }
     }
 }
diff --git a/daemon/src/ringdht/ringaccount.cpp b/daemon/src/ringdht/ringaccount.cpp
index b94087a5a38d451b19daf3e57037be60303d4988..cbdb671129aeb42fc2cdb27ba53478e3e2aa72a1 100644
--- a/daemon/src/ringdht/ringaccount.cpp
+++ b/daemon/src/ringdht/ringaccount.cpp
@@ -240,6 +240,9 @@ RingAccount::createOutgoingCall(const std::shared_ptr<SIPCall>& call, const std:
             getPublishedIpAddress() : localAddress;
     }
 
+    /* fallback on local address */
+    if (not addrSdp) addrSdp = localAddress;
+
     // Initialize the session using ULAW as default codec in case of early media
     // The session should be ready to receive media once the first INVITE is sent, before
     // the session initialization is completed
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index e17405f8daeaa5933cf1d1be0804e4eaa0eafc21..2cbd92b08af26588e2b138da54a1568bb9a4e147 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -239,6 +239,9 @@ SIPAccount::newOutgoingCall(const std::string& id, const std::string& toUrl)
             getPublishedIpAddress() : localAddress;
     }
 
+    /* fallback on local address */
+    if (not addrSdp) addrSdp = localAddress;
+
     // Initialize the session using ULAW as default codec in case of early media
     // The session should be ready to receive media once the first INVITE is sent, before
     // the session initialization is completed
@@ -1419,7 +1422,7 @@ SIPAccount::getContactHeader(pjsip_transport* t)
         hostname_,
         address, port);
 
-    if (getUseUPnP()) {
+    if (getUseUPnP() and getUPnPIpAddress()) {
         address = getUPnPIpAddress().toString();
         port = publishedPortUsed_;
         useUPnPAddressPortInVIA();
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index ca0b471e6aa2155a8abe004d9a09f64c8aeb9320..511f70186ddb325218112f44f2c49eee669530a2 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -326,6 +326,9 @@ transaction_request_cb(pjsip_rx_data *rdata)
                     ? account->getPublishedIpAddress() : addrToUse;
     }
 
+    /* fallback on local address */
+    if (not addrSdp) addrSdp = addrToUse;
+
     call->setConnectionState(Call::PROGRESSING);
     call->setPeerNumber(peerNumber);
     call->setDisplayName(displayName);
@@ -892,6 +895,7 @@ sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
 
     // FIXME : for now, use the same address family as the SIP transport
     auto family = pjsip_transport_type_get_af(account.getTransportType());
+    IpAddr addrToUse = ip_utils::getInterfaceAddr(account.getLocalInterface(), family);
 
     IpAddr address;
     if (account.getUseUPnP()) {
@@ -899,11 +903,13 @@ sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
         address = account.getPublishedSameasLocal() ?
             account.getUPnPIpAddress() : account.getPublishedIpAddress();
     } else {
-        address = account.getPublishedSameasLocal()
-                    ? IpAddr(ip_utils::getInterfaceAddr(account.getLocalInterface(), family))
-                    : account.getPublishedIpAddress();
+        address = account.getPublishedSameasLocal() ?
+            addrToUse : account.getPublishedIpAddress();
     }
 
+    /* fallback on local address */
+    if (not address) address = addrToUse;
+
     call->setCallMediaLocal(address);
 
     auto& localSDP = call->getSDP();