diff --git a/lib/selection.c b/lib/selection.c
index 8031fb74db2470589e7b9f41ce05d46cf56ae0e1..d6ef22fbf0810550b2e1fed8d09634ab5df3a2f2 100644
--- a/lib/selection.c
+++ b/lib/selection.c
@@ -125,6 +125,7 @@ void bytes_to_ip(uint8_t *bytes, size_t len, uint16_t port, union inaddr *dst)
 		dst->ip4.sin_port = htons(port);
 		break;
 	case sizeof(struct in6_addr):
+		memset(&dst->ip6, 0, sizeof(dst->ip6)); // avoid uninit surprises
 		dst->ip6.sin6_family = AF_INET6;
 		memcpy(&dst->ip6.sin6_addr, bytes, len);
 		dst->ip6.sin6_port = htons(port);
@@ -246,19 +247,18 @@ static void check_network_settings(struct address_state *address_state,
 	}
 }
 
-void update_address_state(struct address_state *state, uint8_t *address,
+void update_address_state(struct address_state *state, union inaddr *address,
 			  size_t address_len, struct kr_query *qry)
 {
-	union inaddr tmp_address;
-	bytes_to_ip(address, address_len, 0, &tmp_address);
-	check_tls_capable(state, qry->request, &tmp_address.ip);
+	check_tls_capable(state, qry->request, &address->ip);
 	/* TODO: uncomment this once we actually use the information it collects
 	check_tcp_connections(address_state, qry->request, &tmp_address.ip);
 	*/
 	check_network_settings(state, address_len, qry->flags.NO_IPV4,
 			       qry->flags.NO_IPV6);
 	state->rtt_state =
-		get_rtt_state(address, address_len, &qry->request->ctx->cache);
+		get_rtt_state(ip_to_bytes(address, address_len),
+		              address_len, &qry->request->ctx->cache);
 	invalidate_dead_upstream(
 		state, qry->request->ctx->cache_rtt_tout_retry_interval);
 #ifdef SELECTION_CHOICE_LOGGING
@@ -403,11 +403,25 @@ struct kr_transport *select_transport(struct choice choices[], int choices_len,
 			break;
 		default:
 			assert(0);
-			break;
+			return NULL;
 		}
 	}
 
-	bytes_to_ip(chosen->address, chosen->address_len, port, &transport->address);
+	switch (chosen->address_len)
+	{
+	case sizeof(struct in_addr):
+		transport->address.ip4 = chosen->address.ip4;
+		transport->address.ip4.sin_port = htons(port);
+		break;
+	case sizeof(struct in6_addr):
+		transport->address.ip6 = chosen->address.ip6;
+		transport->address.ip6.sin6_port = htons(port);
+		break;
+	default:
+		assert(0);
+		return NULL;
+	}
+
 	transport->address_len = chosen->address_len;
 
 	if (choice_index) {
diff --git a/lib/selection.h b/lib/selection.h
index 113a468bf22a2522f1d70f6b945ce37f193d5392..18cefccc26ddfce61a6119d83fdb003c7b1c9ff3 100644
--- a/lib/selection.h
+++ b/lib/selection.h
@@ -164,7 +164,7 @@ struct address_state {
  * @brief Array of these is one of inputs for the actual selection algorithm (`select_transport`)
  */
 struct choice {
-	uint8_t *address;
+	union inaddr address;
 	size_t address_len;
 	struct address_state *address_state;
 	/** used to overwrite the port number;
@@ -240,5 +240,5 @@ uint8_t *ip_to_bytes(const union inaddr *src, size_t len);
 /**
  * @internal Fetch per-address information from various sources.
  */
-void update_address_state(struct address_state *state, uint8_t *address,
+void update_address_state(struct address_state *state, union inaddr *address,
 			  size_t address_len, struct kr_query *qry);
diff --git a/lib/selection_forward.c b/lib/selection_forward.c
index d741410067d46ab6464a8019a047546b52f53ab3..b311fc9f95752cedb297bb6c550fead23b8a303a 100644
--- a/lib/selection_forward.c
+++ b/lib/selection_forward.c
@@ -59,8 +59,7 @@ void forward_choose_transport(struct kr_query *qry,
 		struct address_state *addr_state = &local_state->addr_states[i];
 		addr_state->ns_name = (knot_dname_t *)"";
 
-		update_address_state(addr_state, ip_to_bytes(address, addr_len),
-				     addr_len, qry);
+		update_address_state(addr_state, address, addr_len, qry);
 
 		if (addr_state->generation == -1) {
 			continue;
@@ -68,7 +67,7 @@ void forward_choose_transport(struct kr_query *qry,
 		addr_state->choice_array_index = i;
 
 		choices[valid++] = (struct choice){
-			.address = ip_to_bytes(address, addr_len),
+			.address = *address,
 			.address_len = addr_len,
 			.address_state = addr_state,
 			.port = port,
diff --git a/lib/selection_iter.c b/lib/selection_iter.c
index 4e8642d7aea16c5007cd46bb35bebe0530e18c73..388f29f8ea85941daa9a3b5789d4014ce3214d4d 100644
--- a/lib/selection_iter.c
+++ b/lib/selection_iter.c
@@ -124,7 +124,9 @@ static void unpack_state_from_zonecut(struct iter_local_state *local_state,
 			} else if (address_len == sizeof(struct in6_addr)) {
 				name_state->aaaa_state = RECORD_RESOLVED;
 			}
-			update_address_state(address_state, address, address_len, qry);
+			union inaddr tmp_address;
+			bytes_to_ip(address, address_len, 0, &tmp_address);
+			update_address_state(address_state, &tmp_address, address_len, qry);
 		}
 	}
 	trie_it_free(it);
@@ -143,10 +145,10 @@ static int get_valid_addresses(struct iter_local_state *local_state,
 		if (address_state->generation == local_state->generation &&
 		    !address_state->unrecoverable_errors) {
 			choices[count] = (struct choice){
-				.address = address,
 				.address_len = address_len,
 				.address_state = address_state,
 			};
+			bytes_to_ip(address, address_len, 0, &choices[count].address);
 			count++;
 		}
 	}