u8 *private_key = nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]);
                u8 public_key[NOISE_PUBLIC_KEY_LEN];
                struct wg_peer *peer, *temp;
+               bool send_staged_packets;
 
                if (!crypto_memneq(wg->static_identity.static_private,
                                   private_key, NOISE_PUBLIC_KEY_LEN))
                }
 
                down_write(&wg->static_identity.lock);
-               wg_noise_set_static_identity_private_key(&wg->static_identity,
-                                                        private_key);
-               list_for_each_entry_safe(peer, temp, &wg->peer_list,
-                                        peer_list) {
+               send_staged_packets = !wg->static_identity.has_identity && netif_running(wg->dev);
+               wg_noise_set_static_identity_private_key(&wg->static_identity, private_key);
+               send_staged_packets = send_staged_packets && wg->static_identity.has_identity;
+
+               wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
+               list_for_each_entry_safe(peer, temp, &wg->peer_list, peer_list) {
                        wg_noise_precompute_static_static(peer);
                        wg_noise_expire_current_peer_keypairs(peer);
+                       if (send_staged_packets)
+                               wg_packet_send_staged_packets(peer);
                }
-               wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
                up_write(&wg->static_identity.lock);
        }
 skip_set_private_key:
 
 n1 ping -W 1 -c 1 192.168.241.2
 [[ $(n2 wg show wg0 endpoints) == "$pub1       10.0.0.3:1" ]]
 
-ip1 link del veth1
-ip1 link del veth3
-ip1 link del wg0
-ip2 link del wg0
+ip1 link del dev veth3
+ip1 link del dev wg0
+ip2 link del dev wg0
+
+# Make sure persistent keep alives are sent when an adapter comes up
+ip1 link add dev wg0 type wireguard
+n1 wg set wg0 private-key <(echo "$key1") peer "$pub2" endpoint 10.0.0.1:1 persistent-keepalive 1
+read _ _ tx_bytes < <(n1 wg show wg0 transfer)
+[[ $tx_bytes -eq 0 ]]
+ip1 link set dev wg0 up
+read _ _ tx_bytes < <(n1 wg show wg0 transfer)
+[[ $tx_bytes -gt 0 ]]
+ip1 link del dev wg0
+# This should also happen even if the private key is set later
+ip1 link add dev wg0 type wireguard
+n1 wg set wg0 peer "$pub2" endpoint 10.0.0.1:1 persistent-keepalive 1
+read _ _ tx_bytes < <(n1 wg show wg0 transfer)
+[[ $tx_bytes -eq 0 ]]
+ip1 link set dev wg0 up
+read _ _ tx_bytes < <(n1 wg show wg0 transfer)
+[[ $tx_bytes -eq 0 ]]
+n1 wg set wg0 private-key <(echo "$key1")
+read _ _ tx_bytes < <(n1 wg show wg0 transfer)
+[[ $tx_bytes -gt 0 ]]
+ip1 link del dev veth1
+ip1 link del dev wg0
 
 # We test that Netlink/IPC is working properly by doing things that usually cause split responses
 ip0 link add dev wg0 type wireguard