VPC peering routes not propagating between shared VPC and service project, blocking inter-service communication

After setting up VPC peering between a host project’s shared VPC and a service project’s standalone VPC, routes are not propagating as expected. Services in the service project cannot communicate with resources in the shared VPC, even though the peering connection shows as active in both directions.

We’ve configured the shared VPC architecture properly with the host project, and the service project has necessary permissions. The VPC peering was established using gcloud CLI, but custom routes we’ve added to the host VPC aren’t visible in the service project’s route table.


gcloud compute networks peerings create peer-to-shared \
  --network=service-vpc \
  --peer-network=shared-vpc

The peering shows ACTIVE status, but ping tests between VMs fail. We need bidirectional communication for our microservices architecture. Is there a specific flag for custom route propagation that we’re missing?

Shared VPC adds complexity here. The service project’s compute.networkUser role only grants subnet-level access, not VPC-level peering management. You need compute.networkAdmin on the host project to modify peering settings. Also, be aware that if you’re using Cloud Router for dynamic routing in the shared VPC, those routes won’t propagate through VPC peering even with custom route flags enabled. Static routes work, but not dynamically learned routes.

Your configuration has several issues that need systematic resolution to achieve proper routing between your shared VPC and service project.

VPC Peering Configuration: The peering command you used is missing the critical flags for custom route exchange. VPC peering only exchanges subnet routes by default. For custom routes to propagate, you must enable bidirectional route exchange:


gcloud compute networks peerings update peer-to-shared \
  --network=service-vpc \
  --import-custom-routes \
  --export-custom-routes

You need to run this for both peering connections (one in each direction). Without these flags, only directly connected subnet routes are visible across the peering.

Custom Route Propagation: After enabling route exchange, verify which routes are actually being shared. Not all custom routes propagate through peering. Routes learned via Cloud Router (BGP) do NOT traverse VPC peering connections. Only static custom routes propagate when exchange is enabled. Check your route tables:


gcloud compute routes list --filter="network:shared-vpc"
gcloud compute routes list --filter="network:service-vpc"

Look for routes with next-hop types that are compatible with peering propagation.

Shared VPC Architecture: This is crucial - if your service project is already attached to the shared VPC as a service project, you shouldn’t be creating a separate VPC in the service project and peering it back to the shared VPC. This creates a routing loop and conflicts. The proper architecture is:

Option A: Service project uses shared VPC subnets directly (no separate VPC needed)

Option B: Service project has its own VPC that peers with a DIFFERENT VPC (not the shared VPC it’s attached to)

If you need isolation while using shared VPC, use firewall rules and separate subnets, not VPC peering. If you genuinely need a separate VPC in the service project that communicates with the shared VPC, the service project should NOT be attached as a shared VPC service project - it should remain standalone and use peering exclusively.

For your use case, I recommend removing the separate VPC from the service project and using the shared VPC with proper firewall segmentation. If you absolutely need the separate VPC, detach the service project from the shared VPC and rely solely on peering with proper route exchange enabled.

You’re right about the custom routes flag. I checked and we didn’t enable import/export. However, I’m confused about the shared VPC aspect. Since one side is a shared VPC in a host project, do we need special IAM permissions to modify the peering configuration? The service project has compute.networkUser role on the shared VPC subnets.

Also verify that your firewall rules allow traffic between the peered networks. VPC peering only handles routing - you still need appropriate ingress and egress firewall rules in both VPCs. Common mistake is assuming peering automatically permits traffic. Create firewall rules that allow traffic from the peer VPC’s IP ranges.

VPC peering doesn’t automatically export custom routes - only subnet routes are exchanged by default. You need to explicitly enable custom route exchange using the --export-custom-routes and --import-custom-routes flags when creating the peering. Check your current peering configuration with ‘gcloud compute networks peerings list’ to see if these flags are set.

I’ve dealt with this exact scenario multiple times. The shared VPC complicates things because you’re dealing with two different organizational constructs - shared VPC service attachment and VPC peering. Make sure you’re not trying to peer the service project’s VPC with the same shared VPC it’s already attached to as a service project. That creates conflicting routing paths. If you need isolation, use separate VPCs and peer them correctly with proper route exchange flags.