diff --git a/lib/socket.h b/lib/socket.h
index 03c15dcd..90dcc600 100644
--- a/lib/socket.h
+++ b/lib/socket.h
@@ -93,6 +93,7 @@ void sk_set_rbsize(sock *s, uint val);	/* Resize RX buffer */
 void sk_set_tbsize(sock *s, uint val);	/* Resize TX buffer, keeping content */
 void sk_set_tbuf(sock *s, void *tbuf);	/* Switch TX buffer, NULL-> return to internal */
 void sk_dump_all(void);
+void sk_free(resource *r);
 
 int sk_is_ipv4(sock *s);		/* True if socket is IPv4 */
 int sk_is_ipv6(sock *s);		/* True if socket is IPv6 */
diff --git a/proto/bmp/bmp.c b/proto/bmp/bmp.c
index acae659e..f1446fe2 100644
--- a/proto/bmp/bmp.c
+++ b/proto/bmp/bmp.c
@@ -166,6 +166,9 @@ enum bmp_term_reason {
 // Default chunk size request when memory allocation
 #define DEFAULT_MEM_BLOCK_SIZE 4096
 
+// Timeout for connection to the BMP collector
+#define CONNECT_TIMEOUT_SEC (10 S)
+
 // Timeout for connection to the BMP collector retry
 #define CONNECT_RETRY_SEC (10 S)
 
@@ -188,10 +191,17 @@ enum bmp_term_reason {
   } while (0)
 
 
+// Callback after successfully connected to BMP station
+static void
+bmp_station_connected(struct birdsock *sk);
+
 // Handle BIRD socket error event
 static void
 bmp_sock_err(sock *sk, int err);
 
+static void
+bmp_connection_retry(timer *t);
+
 static void
 bmp_send_peer_up_notif_msg(struct bmp_proto *p, const struct bgp_proto *bgp,
   const byte* tx_data, const size_t tx_data_size,
@@ -292,6 +302,7 @@ bmp_fire_tx(void *p_)
     "Called BMP TX event handler when there is not any data to send"
   );
 
+  int rv;
   size_t cnt = 0; // Counts max packets which we want to send per TX slot
   struct bmp_data_node *tx_data;
   struct bmp_data_node *tx_data_next;
@@ -304,14 +315,18 @@ bmp_fire_tx(void *p_)
 
     size_t data_size = tx_data->data_size;
     memcpy(buf, tx_data->data, tx_data->data_size);
+    rv = sk_send(p->sk, data_size);
+    if (rv < 0) {
+      log(L_ERR "Failed to send BMP PDU");
+      return;
+    }
+
     mb_free(tx_data->data);
     rem_node((node *) tx_data);
     mb_free(tx_data);
-    IF_COND_TRUE_PRINT_ERR_MSG_AND_RETURN_OPT_VAL(
-      (sk_send(p->sk, data_size) <= 0),
-      "Failed to send BMP packet"
-    );
-
+    if (rv == 0) {
+      return;
+    }
     // BMP packets should be treat with lowest priority when scheduling sending
     // packets to target. That's why we want to send max. 32 packets per event
     // call
@@ -336,6 +351,7 @@ bmp_tx(struct birdsock *sk)
 static inline int
 bmp_open_socket(struct bmp_proto *p)
 {
+  p->sk_err = 0;
   sock *s = p->sk;
   s->daddr = p->station_ip;
   s->dport = p->station_port;
@@ -349,6 +365,22 @@ bmp_open_socket(struct bmp_proto *p)
   return rc;
 }
 
+static void
+bmp_connection_timeout(timer *t)
+{
+  struct bmp_proto *p = t->data;
+  if (p->sk_err == ECONNREFUSED) {
+    if (sk_open(p->sk) < 0)
+      sk_log_error(p->sk, p->p.name);
+
+    p->sk_err = 0;
+  }
+  else {
+    log(L_DEBUG "Successfully connected to BMP station");
+    tm_stop(t);
+  }
+}
+
 static void
 bmp_connection_retry(timer *t)
 {
@@ -356,10 +388,11 @@ bmp_connection_retry(timer *t)
 
   if (bmp_open_socket(p) < 0)
   {
-    log(L_DEBUG "Failed to connect to BMP station");
     return;
   }
 
+  p->sk->tx_hook = bmp_station_connected;
+  p->sk->err_hook = bmp_sock_err;
   log(L_DEBUG "Connected to BMP station after connection retry");
   tm_stop(t);
 }
@@ -367,8 +400,13 @@ bmp_connection_retry(timer *t)
 void
 bmp_sock_err(sock *sk, int err)
 {
-  // There is not special case to handle error.
-  // Thanks for that we avoid flooding by logs.
+  if (err == ECONNREFUSED)
+  {
+    struct bmp_proto *p = sk->data;
+    p->sk_err = err;
+    sk_free((resource *)p->sk);
+    tm_start(p->connect_retry_timer, CONNECT_RETRY_SEC);
+  }
 }
 
 static inline void
@@ -517,15 +555,19 @@ bmp_open(const struct proto *P)
   p->connect_retry_timer = NULL;
   if (bmp_open_socket(p) < 0)
   {
-    log(L_DEBUG "Failed to connect to BMP station");
+    log(L_DEBUG "Failed to connect to BMP station immediately");
     p->connect_retry_timer = tm_new_init(P->pool, bmp_connection_retry, p,
                                    CONNECT_RETRY_SEC, 0 /* not randomized */);
     tm_start(p->connect_retry_timer, CONNECT_RETRY_SEC);
-    p->station_connected = false;
   }
   else
   {
-    log(L_DEBUG "Connected to BMP station");
+    // This is extra check if BMP has been successfully connected to the BMP station,
+    // because if service is not running on the server, then sk_open() still returns
+    // success
+    p->connect_retry_timer = tm_new_init(P->pool, bmp_connection_timeout, p,
+                                   CONNECT_TIMEOUT_SEC, 0 /* not randomized */);
+    tm_start(p->connect_retry_timer, CONNECT_TIMEOUT_SEC);
   }
 }
 
@@ -1042,7 +1084,7 @@ bmp_send_termination_msg(struct bmp_proto *p,
   IF_COND_TRUE_PRINT_ERR_MSG_AND_RETURN_OPT_VAL(
     sk_send(p->sk, bmp_buffer_pos(&stream)) < 0,
     "Failed to send BMP termination message"
-    );
+  );
 
   bmp_buffer_free(&stream);
 }
diff --git a/proto/bmp/bmp.h b/proto/bmp/bmp.h
index a43827b3..902d570c 100644
--- a/proto/bmp/bmp.h
+++ b/proto/bmp/bmp.h
@@ -83,6 +83,7 @@ struct bmp_proto {
   struct rt_table_info rt_table_in_pre_policy; // Pre-policy route import table 
   bool station_connected;          // Flag that stores connection status with BMP station
   bool started;                    // Flag that stores running status of BMP instance
+  int sk_err;                      // Stores last socket error code
 };
 
 /**
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index 5e4d9573..2875e179 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -792,7 +792,7 @@ sk_ssh_free(sock *s)
 }
 #endif
 
-static void
+void
 sk_free(resource *r)
 {
   sock *s = (sock *) r;
