Hi @tedbanks,
Welcome to Google Cloud Community!
This situation suggests an environment configuration or network access issue specific to the Cloud Run environment. Here are some of the possible causes of the error you are seeing and how to resolve them:
- Seeing the API key in console.log is a good sign, but it doesn’t guarantee that the Generative Language API client is using it correctly inside the Node.js app. Cloud Run may handle environment variables or parse them slightly differently compared to a local environment like Cloud Shell. Instead of depending on the client library to automatically use your environment variable, manually pass the API key when creating the Generative Language client. Also, make sure the library version matches between local and Cloud Run — version mismatches can cause weird issues. Finally, just in case, double-check that no encoding problems are affecting the key when read from the environment.
- Even though you're calling a Google API, Cloud Run still runs inside Google's infrastructure. If your service is restricted by VPC Service Controls or has limited egress settings, it might block access to generativelanguage.googleapis.com. When that happens, the API can’t reach the endpoint to check the key, which could lead to an “API key not valid” error.
- Review VPC Service Controls: If your project uses VPC Service Controls, make sure the generativelanguage.googleapis.com API is allowed. Also, check that your Cloud Run service is properly included within the access perimeter.
- Egress Configuration: Look at your Cloud Run network settings. If "Allow all traffic" is selected, you’re likely fine. But if you're routing all traffic through a VPC, confirm that the VPC allows outbound connections to Google APIs.
- Using Google’s Internal Network: To improve reliability, consider setting up Private Google Access or using Serverless VPC Access with a VPC that supports it. This routes API calls over Google’s internal network, helping avoid potential external connectivity issues.
- The TypeError: Cannot convert argument to a ByteString... after Base64 encoding is an important clue. It indicates that although the key may be correctly retrieved from Secret Manager, there’s likely a formatting or type issue with it right before it’s passed to the API client.
- Remove Base64 Encoding: Base64 encoding the API key appears to be causing problems. It's usually not needed unless there’s a specific reason. It's better to store the plain key directly in the Secret Manager.
- Check the Data Type: Make sure the API key from process.env.GEMINI_API_KEY is being treated as a string. Environment variables can sometimes be misinterpreted. You can confirm by logging typeof GEMINI_API_KEY before using it in your code.
- Watch for Extra Spaces:
Even small issues like leading or trailing spaces in the API key can break authentication. While tools like curl might reveal this, it’s good practice to trim the key in your code
- While Cloud Shell closely resembles a deployed environment, there can be small but important differences in how Node.js handles environment variables or networking when running in Cloud Run. You can create a simple Cloud Run service that only initializes the Generative Language API client using the GEMINI_API_KEY from process.env and makes one basic API call (like generating a short message). This helps pinpoint whether the issue is with how the key is being handled in the Cloud Run environment.
- It is also possible that the Gemini Model you are using might not be available. As per Google’s documentation the Gemini 1.5 Pro and Gemini 1.5 Flash models are no longer accessible to projects that haven’t previously used them. This includes all newly created projects.
Was this helpful? If so, please accept this answer as “Solution”. If you need additional assistance, reply here within 2 business days and I’ll be happy to help.