diff --git a/.changelog/14598.txt b/.changelog/14598.txt
new file mode 100644
index 0000000000..f76b4958d1
--- /dev/null
+++ b/.changelog/14598.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+connect: Fixed a bug where old root CAs would be removed from the primary datacenter after switching providers and restarting the cluster.
+```
diff --git a/agent/consul/leader_connect_ca.go b/agent/consul/leader_connect_ca.go
index 8f32f6e2c3..8d2bf9cb86 100644
--- a/agent/consul/leader_connect_ca.go
+++ b/agent/consul/leader_connect_ca.go
@@ -564,22 +564,9 @@ func (c *CAManager) primaryInitialize(provider ca.Provider, conf *structs.CAConf
 		return nil
 	}
 
-	// Get the highest index
-	idx, _, err := state.CARoots(nil)
-	if err != nil {
+	if err := c.persistNewRootAndConfig(provider, rootCA, conf); err != nil {
 		return err
 	}
-
-	// Store the root cert in raft
-	_, err = c.delegate.ApplyCARequest(&structs.CARequest{
-		Op:    structs.CAOpSetRoots,
-		Index: idx,
-		Roots: []*structs.CARoot{rootCA},
-	})
-	if err != nil {
-		return fmt.Errorf("raft apply failed: %w", err)
-	}
-
 	c.setCAProvider(provider, rootCA)
 
 	c.logger.Info("initialized primary datacenter CA with provider", "provider", conf.Provider)
diff --git a/agent/consul/leader_connect_test.go b/agent/consul/leader_connect_test.go
index c8b361b03b..bf6fa95221 100644
--- a/agent/consul/leader_connect_test.go
+++ b/agent/consul/leader_connect_test.go
@@ -691,6 +691,71 @@ func TestConnectCA_ConfigurationSet_RootRotation_Secondary(t *testing.T) {
 	require.NoError(t, err)
 }
 
+func TestCAManager_Initialize_Vault_KeepOldRoots_Primary(t *testing.T) {
+	ca.SkipIfVaultNotPresent(t)
+
+	if testing.Short() {
+		t.Skip("too slow for testing.Short")
+	}
+
+	t.Parallel()
+
+	testVault := ca.NewTestVaultServer(t)
+	defer testVault.Stop()
+
+	dir1pre, s1pre := testServer(t)
+	defer os.RemoveAll(dir1pre)
+	defer s1pre.Shutdown()
+	codec := rpcClient(t, s1pre)
+	defer codec.Close()
+
+	testrpc.WaitForLeader(t, s1pre.RPC, "dc1")
+
+	// Update the CA config to use Vault - this should force the generation of a new root cert.
+	vaultCAConf := &structs.CAConfiguration{
+		Provider: "vault",
+		Config: map[string]interface{}{
+			"Address":             testVault.Addr,
+			"Token":               testVault.RootToken,
+			"RootPKIPath":         "pki-root/",
+			"IntermediatePKIPath": "pki-intermediate/",
+		},
+	}
+
+	args := &structs.CARequest{
+		Datacenter: "dc1",
+		Config:     vaultCAConf,
+	}
+	var reply interface{}
+
+	require.NoError(t, msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationSet", args, &reply))
+
+	// Should have 2 roots now.
+	_, roots, err := s1pre.fsm.State().CARoots(nil)
+	require.NoError(t, err)
+	require.Len(t, roots, 2)
+
+	// Shutdown s1pre and restart it to trigger the primary CA init.
+	s1pre.Shutdown()
+
+	dir1, s1 := testServerWithConfig(t, func(c *Config) {
+		c.DataDir = s1pre.config.DataDir
+		c.NodeName = s1pre.config.NodeName
+		c.NodeID = s1pre.config.NodeID
+	})
+	defer os.RemoveAll(dir1)
+	defer s1.Shutdown()
+
+	testrpc.WaitForLeader(t, s1.RPC, "dc1")
+
+	// Roots should be unchanged
+	_, rootsAfterRestart, err := s1.fsm.State().CARoots(nil)
+	require.NoError(t, err)
+	require.Len(t, rootsAfterRestart, 2)
+	require.Equal(t, roots[0].ID, rootsAfterRestart[0].ID)
+	require.Equal(t, roots[1].ID, rootsAfterRestart[1].ID)
+}
+
 func TestCAManager_Initialize_Vault_FixesSigningKeyID_Primary(t *testing.T) {
 	ca.SkipIfVaultNotPresent(t)