diff --git a/src/lib/swim/swim_io.c b/src/lib/swim/swim_io.c
index c8558c43e48396337a211379daf5a012ba0205ef..0002472fadbda1580dcd5e5c5a48c6ff3dfd456d 100644
--- a/src/lib/swim/swim_io.c
+++ b/src/lib/swim/swim_io.c
@@ -512,8 +512,26 @@ static inline void
 swim_complete_send(struct swim_scheduler *scheduler, struct swim_task *task,
 		   ssize_t size)
 {
-	if (size < 0)
-		diag_log();
+	if (size < 0) {
+		bool is_critical = true;
+		int err = diag_last_error(diag_get())->saved_errno;
+#if TARGET_OS_DARWIN
+		/*
+		 * On Mac this error happens regularly if SWIM is bound to
+		 * the localhost and tries to broadcast out of the machine. This
+		 * is not critical, because will happen in the tests a lot, and
+		 * in prod it simply should not bind to localhost if there are
+		 * multiple machines in the cluster. Besides, Mac as a platform
+		 * is not supposed to be used in prod.
+		 */
+		is_critical = (err != EADDRNOTAVAIL);
+#else
+		/* The same as EADDRNOTAVAIL, but happens on Linux as EINVAL. */
+		is_critical = (err != EINVAL);
+#endif
+		if (is_critical)
+			diag_log();
+	}
 	if (task->complete != NULL)
 		task->complete(task, scheduler, size);
 }
diff --git a/src/lib/swim/swim_transport_udp.c b/src/lib/swim/swim_transport_udp.c
index c0317a20b851dcbec33c420079bfdac7d81aa93d..12626cc49f7cd34cbf8c457003f9136cac849af8 100644
--- a/src/lib/swim/swim_transport_udp.c
+++ b/src/lib/swim/swim_transport_udp.c
@@ -80,25 +80,27 @@ swim_transport_bind(struct swim_transport *transport,
 		return 0;
 	}
 
+	int is_on = 1;
+	int real_port = new_addr->sin_port;
 	int fd = sio_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 	if (fd < 0)
 		return -1;
-	if (sio_bind(fd, (struct sockaddr *) addr, addr_len) != 0 ||
-	    evio_setsockopt_server(fd, AF_INET, SOCK_DGRAM) != 0) {
+	if (sio_bind(fd, (struct sockaddr *) addr, addr_len) != 0) {
 		if (errno == EADDRINUSE)
 			diag_set(SocketError, sio_socketname(fd), "bind");
-		close(fd);
-		return -1;
+		goto end_error;
 	}
-	int real_port = new_addr->sin_port;
+	if (sio_setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &is_on,
+			   sizeof(is_on)) != 0)
+		goto end_error;
+	if (evio_setsockopt_server(fd, AF_INET, SOCK_DGRAM) != 0)
+		goto end_error;
 	if (is_new_port_any) {
 		struct sockaddr_in real_addr;
 		addr_len = sizeof(real_addr);
 		if (sio_getsockname(fd, (struct sockaddr *) &real_addr,
-				    &addr_len) != 0) {
-			close(fd);
-			return -1;
-		}
+				    &addr_len) != 0)
+			goto end_error;
 		real_port = real_addr.sin_port;
 	}
 	if (transport->fd != -1)
@@ -107,6 +109,9 @@ swim_transport_bind(struct swim_transport *transport,
 	transport->addr = *new_addr;
 	transport->addr.sin_port = real_port;
 	return 0;
+end_error:
+	close(fd);
+	return -1;
 }
 
 void