Cloud Run: API Gateway cannot reach internal services (ingress = internal-and-cloud-load-balancing)

I have three Spring Boot microservices deployed on Google Cloud Run:

  1. API Gateway

    • Ingress: all

    • Publicly accessible

  2. Service A

    • Returns: “hello from A”

    • Desired ingress: internal-and-cloud-load-balancing

  3. Service B

    • Returns: “hello from B and hello from A”

    • Calls Service A internally

    • Desired ingress: internal-and-cloud-load-balancing

My goal is:

  • Only the API Gateway should be exposed to the internet.

  • Services A and B should be internal-only (not publicly reachable).

  • The call flow should be:
    API Gateway → Service B → Service A


Problem

When I set Services A and B to ingress = internal-and-cloud-load-balancing, the API Gateway cannot reach them.
I consistently get:

404 Not Found

I initially deployed everything in europe-west1. After reading this related question:
Google Cloud Run 404 Error on internal traffic between services

…I tried deploying in other regions as well, but the issue persists.

I also checked the official documentation:
https://cloud.google.com/run/docs/securing/ingress (cloud.google.com in Bing)

…but I still cannot make API Gateway reach internal Cloud Run services.


What I want to understand

  • Do Cloud Run services with internal-and-cloud-load-balancing require a Shared VPC even if all services are in the same project?

  • Do I need a Serverless VPC Connector for API Gateway → Cloud Run internal traffic?

  • Is API Gateway even able to call Cloud Run services that are restricted to internal ingress, or is an additional load balancer required?


Additional context

  • All services are deployed in the same region and same project.

  • When I switch ingress back to all, everything works as expected.

2 Likes

Hello @mazvangui,

Ah, the joy of API Gateway :sweat_smile:

So, if I understand correctly, you want only the API Gateway to be reachable from the internet?

From what I know, using Internal or Internal and Cloud Load Balancing as Available network ingress settings for Cloud Run won’t allow API Gateway to reach Cloud Run.

If you really want to have Cloud Run A and B set to Internal or Internal + LB only, you will have to use Apigee that can work with VPC, as API Gateway does not support this to this day.

That said, I understand that Apigee could be overwhelming and/or overkill.

Here’s what I would do in your case:

  • Set Cloud Run A & B to Ingress All + Required Auth
  • Manage Service-to-Service Authentication between Cloud Run, B → A
  • Stick with API Gateway, as it’s simple and straightforward. Even though it can be a pain to configure, it’s now compatible with OpenAPI v3, which is very nice
  • Make API Gateway able to contact Cloud Run B

So it would work like this:

:bust_in_silhouette:-> API Gateway → Service Account → Cloud Run B → Service Account → Cloud Run A

You could probably manage two VPCs to have Cloud Run B connected to Cloud Run A’s VPC, allowing Cloud Run B to connect to API Gateway and Cloud Run A to be isolated.

But that seems like an over-complication, and I wouldn’t worry about it at all with Ingress All + Required Auth

I was just facing this same problem, i thought for sure there was a way to lock down the function and have it only accessible through the gateway, but… here we are :downcast_face_with_sweat: .