diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp
index 427aa79a..d5bb0265 100644
--- a/I2NPProtocol.cpp
+++ b/I2NPProtocol.cpp
@@ -330,7 +330,10 @@ namespace i2p
 				i2p::tunnel::tunnels.AddInboundTunnel (static_cast<i2p::tunnel::InboundTunnel *>(tunnel));
 			}
 			else
+			{
 				LogPrint ("Inbound tunnel ", tunnel->GetTunnelID (), " has been declined");
+				tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed);	
+			}
 		}
 		else
 		{
@@ -386,7 +389,10 @@ namespace i2p
 				i2p::tunnel::tunnels.AddOutboundTunnel (static_cast<i2p::tunnel::OutboundTunnel *>(tunnel));
 			}	
 			else
+			{
 				LogPrint ("Outbound tunnel ", tunnel->GetTunnelID (), " has been declined");
+				tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed);	
+			}
 		}	
 		else
 			LogPrint ("Pending tunnel for message ", replyMsgID, " not found");
diff --git a/Tunnel.cpp b/Tunnel.cpp
index 59eccc94..57c16184 100644
--- a/Tunnel.cpp
+++ b/Tunnel.cpp
@@ -246,7 +246,10 @@ namespace tunnel
 	{
 		auto it = m_PendingTunnels.find(replyMsgID);
 		if (it != m_PendingTunnels.end ())
+		{	
+			it->second->SetState (eTunnelStateBuildReplyReceived);	
 			return it->second;
+		}
 		return nullptr;
 	}	
 
@@ -369,23 +372,35 @@ namespace tunnel
 
 	void Tunnels::ManageTunnels ()
 	{
-		// check pending tunnel. delete non-successive
+		// check pending tunnel. delete failed or timeout
 		uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
 		for (auto it = m_PendingTunnels.begin (); it != m_PendingTunnels.end ();)
 		{	
-			if (it->second->GetState () == eTunnelStatePending) 
+			auto tunnel = it->second;
+			switch (tunnel->GetState ())
 			{
-				if (ts > it->second->GetCreationTime () + TUNNEL_CREATION_TIMEOUT)
-				{
-					LogPrint ("Pending tunnel build request ", it->first, " was not successive. Deleted");
-					delete it->second;
+				case eTunnelStatePending: 
+					if (ts > tunnel->GetCreationTime () + TUNNEL_CREATION_TIMEOUT)
+					{
+						LogPrint ("Pending tunnel build request ", it->first, " timeout. Deleted");
+						delete tunnel;
+						it = m_PendingTunnels.erase (it);
+					}
+					else
+						it++;
+				break;
+				case eTunnelStateBuildFailed:
+					LogPrint ("Pending tunnel build request ", it->first, " failed. Deleted");
+					delete tunnel;
 					it = m_PendingTunnels.erase (it);
-				}
-				else
+				break;
+				case eTunnelStateBuildReplyReceived:
+					// intermidiate state, will be either established of build failed
 					it++;
-			}
-			else
-				it = m_PendingTunnels.erase (it);
+				break;	
+				default:
+					it = m_PendingTunnels.erase (it);
+			}	
 		}	
 		
 		ManageInboundTunnels ();
@@ -405,7 +420,7 @@ namespace tunnel
 				if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
 				{
 					LogPrint ("Tunnel ", tunnel->GetTunnelID (), " expired");
-					auto pool = (*it)->GetTunnelPool ();
+					auto pool = tunnel->GetTunnelPool ();
 					if (pool)
 						pool->TunnelExpired (tunnel);
 					it = m_OutboundTunnels.erase (it);
diff --git a/Tunnel.h b/Tunnel.h
index a848e6b7..73a0e0c6 100644
--- a/Tunnel.h
+++ b/Tunnel.h
@@ -23,12 +23,14 @@ namespace tunnel
 {	
 	const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes	
 	const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute	
-	const int TUNNEL_CREATION_TIMEOUT = 20; // 20 seconds
+	const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds
 	const int STANDARD_NUM_RECORDS = 5; // in VariableTunnelBuild message
 
 	enum TunnelState
 	{
 		eTunnelStatePending,
+		eTunnelStateBuildReplyReceived,
+		eTunnelStateBuildFailed,
 		eTunnelStateEstablished,
 		eTunnelStateTestFailed,
 		eTunnelStateFailed,