I spent a couple of weeks building on Google's new Gemini Enterprise Agent Platform, and hit five things that cost me real time because none of them are documented. Writing them down so the next person can search for the error message and find something.
I built this for the All Things Agentic Hackathon. The project is agent-attest, if you want the context.
1. Agent Registry silently requires interface URLs to be globally unique
This one cost me the most.
I had four agents sharing one container image, which meant they all defaulted to the same port. Registering the first one worked. The other three vanished.
Not errored. Vanished. services.create returned HTTP 200 with an operation name, my code treated that as success, and moved on. The Firestore records I wrote alongside said those agents were registered. The registry said otherwise.
The reason only turned up when I went looking at the operations list:
"message": "The request was invalid: generic::invalid_argument:
Interface URL 'http://localhost:8080' is already in use by another service."
Two things make this expensive:
-
services.createreturns a long-running operation, and the uniqueness check happens asynchronously inside it. If you take the 200 as success you never see the failure. - The first registration always works. So it looks like a race condition, not a constraint on a field nobody thinks of as a key.
The reference for Service.interfaces[] says nothing about uniqueness. If you're registering more than one agent, give each a distinct URL and poll the operation to done rather than trusting the acknowledgement.
2. Agent Gateway doesn't support A2A
The protocols field on an AgentGateway accepts exactly two values:
'protocols': {'items': {'enum': ['MCP', 'PROTOCOL_UNSPECIFIED']}}
There's no A2A.
That matters if you're building the kind of thing the docs encourage. ADK's inter-agent transport is A2A: RemoteA2aAgent on the calling side, to_a2a() on the serving side, agent cards at /.well-known/. So if you build a fleet where agents delegate to each other over the network, Agent Gateway can't sit in front of those calls. It handles MCP tool and server traffic only.
I only found this because the import validator prints its entire JSON schema when you hand it a document it doesn't like, which turned out to be the single most useful error message on the whole platform. Worth remembering as a technique.
While I was in there, three more things from that same schema dump that aren't in the prose docs:
- top-level
networkandsubnetworkare rejected.additionalPropertiesis false, and networking goes undernetworkConfig - you have to pick
googleManagedorselfManaged: a Google-run proxy in a tenant project, or attaching to an existing load balancer -
registriesuses an unusual double-slash form,//agentregistry.googleapis.com/projects/{p}/locations/{l}
3. Google's own Agent Gateway samples set failOpen: true
failOpen on an authorization extension defaults to false, and the reference is clear about what that means: if the extension times out or fails, request processing stops and the client gets a 500.
That's the right default for an authorization control. But every authz sample in the Agent Gateway docs sets it to true.
Copy one of those and your authorization check quietly becomes advisory. Anything that makes the callout unreachable also makes it irrelevant, and an attacker can arrange that. Set it to false explicitly so nobody later assumes the sample was fine.
Related, and worse: CONTENT_AUTHZ can't be made fail-closed at all. Under FULL_DUPLEX_STREAMED the docs say the proxy fail-opens up to the first chunk of body data, and that connection and header failures fail open regardless of what you set failOpen to. If you need a genuine fail-closed guarantee, REQUEST_AUTHZ is your only option.
4. A googleManaged gateway is describable long before it's usable
I created an Agent Gateway. It came back with a name, an etag and timestamps. describe found it straight away. Everything looked fine.
Then binding an authorization policy to it failed:
Failed to update tenant configuration for AgentGateway:
generic::cancelled: agent gateway "agent-attest-gw" is not yet provisioned in the tenant project
A googleManaged gateway gets provisioned asynchronously in a Google-run tenant project. The resource exists in your project well before that finishes. There's no state field to poll, so the only signal you get is the error on whatever operation needs it.
I waited. Four hours later it was still the same message.
If you're scripting this, retry on that specific string and fail fast on anything else. Don't blanket-retry, or you'll turn an unrelated error into a timeout.
5. A private Cloud Run service 404s, it doesn't 403
Not Agent Platform specific, but it ate an afternoon so it's going in.
Deploy a Cloud Run service with --no-allow-unauthenticated and an unauthorised caller gets 404 from the Google frontend, not 403. That's deliberate, so private services don't leak their own existence. It also means "wrong URL" and "no access" are indistinguishable from outside.
Now stack two more things on top:
-
gcloud run services describe --format='value(status.url)'can hand you a legacy hostname that doesn't route, whilegcloud run services listshows the one that does -
gcloud auth print-identity-tokenwith no--audiencesmints a token audienced to gcloud's own OAuth client, which Cloud Run rejects. And--audiencesrequires a service account, so as a human you can't mint one it will accept at all
Result: a service reporting Ready: True and RoutesReady: True, 404ing on every URL you try, that is completely healthy. I spent a long time debugging routing when the problem was authentication.
gcloud run services proxy handles the auth for you. But note it reads status.url too, so if that field is stale the proxy fails as well, and a proxy failure tells you nothing about your container.
The pattern
Four of these five share a shape: something failed, and the thing reporting back said success or said nothing.
An operation that returns 200 and fails later. A launcher that logs Workload completed after refusing to run your workload (that's a Confidential Space one I left out). A gateway that reports created when it means queued. A 404 that means 403.
The habit I ended up with was to stop trusting acknowledgements and check the thing itself. Poll the operation. Read the resource. And when a system gives you a genuinely detailed error, like that schema dump, treat it as the documentation, because sometimes it is.
Written for the All Things Agentic Hackathon. Code is at github.com/iamrobertmoore/agent-attest if you want to see what these were getting in the way of.
Top comments (0)