Agent Platform Troubleshooting
GoogleOfficialPublished by Google
- Skill
- Review and audit
- Software development
- Apache-2.0
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured diagnostic framework for identifying and resolving complex issues within the Google Cloud Gemini Enterprise Agent Platform. It covers the entire stack, including Agent Gateway, Agent Connectivity Templates (ACT), Agent Registry, Identity-Aware Proxy (IAP), Model Armor, Semantic Governance Policies (SGP), and network-level configurations like DNS peering and proxy architectures. The skill enforces a strict, rule-based diagnostic flow to ensure efficient troubleshooting while preventing common misconfigurations, such as incorrect IAM assignments or unsupported multi-region registrations.
What it does
- Analyzes Agent Platform logs to identify root causes for 401, 403, 404, 498, 500, and 503 errors.
- Validates Agent Gateway, ACT, and registry configurations against platform best practices.
- Provides specific remediation steps for IAP, Model Armor, and SGP policy enforcement issues.
- Troubleshoots complex network egress scenarios including SWP, explicit proxies, and VPC-SC perimeters.
- Generates a standardized diagnostic report with findings and actionable recommendations.
- Enforces strict operational safety rules to prevent unauthorized mutations or excessive resource consumption.
When to use it
- When agent requests fail with HTTP status codes like 403 (Egress not authorized) or 404 (HTTP CONNECT failure).
- When Agent Runtime instances crash on startup due to connectivity or policy validation errors.
- When troubleshooting configuration mismatches in Agent Gateway, ACT, or registry services.
- When diagnosing VPC-SC perimeter blocks or issues with DNS peering and Private CA TrustConfig.
- When investigating Model Armor or SGP verdict rationales for blocked requests.
Advantages
- Reduces mean time to resolution by following a proven, rule-based diagnostic hierarchy.
- Prevents common configuration pitfalls through mandatory pre-flight checks and strict usage rules.
- Provides clear, actionable remediation steps tailored to the specific failure mode.
- Ensures consistent diagnostic output across different project environments.
- Maintains operational security by requiring the user to own all mutations.
Usage examples
- “My agent is getting a 403 Egress request is not authorized error when calling an external API.”
- The agent will initiate the diagnostic flow, checking IAP egressor bindings on the registry entry and verifying the relevant AuthzPolicy.
- “Why is my Agent Gateway stuck in PROVISIONING state?”
- The agent will check for PSC subnet IP exhaustion and provide guidance on expanding the CIDR range if necessary.
- “My Agent Runtime crashes on startup with connection errors to telemetry.mtls.googleapis.com.”
- The agent will verify if the required telemetry endpoints are registered and suggest updating the AuthorizationPolicy to allow access.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/google/agent-platform-troubleshooting/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip agent-platform-troubleshooting.zip -d .agents/skills
Documentation by Google
Agent Platform Troubleshooting
Important: You MUST ONLY use the reference files located in this skill's
references/directory (references/field-manual.md,references/known-issues.md,references/agent-gateway.md,references/policies.md,references/agent-registry.md,references/agent-identity.md). Do NOT search for or read external playbooks outside this directory.
Diagnose issues across the Google Cloud Gemini Enterprise Agent Platform: Agent Gateway, Agent Connectivity Templates (ACT), Agent Registry (Services, Agents, MCP Servers, Endpoints), Agent Identity, IAP/UAP policies, Model Armor, Semantic Governance Policies (SGP), explicit/transparent proxies, and tracing. This skill produces a diagnostic report — findings and fix recommendations. It does not apply fixes; the user owns all mutations.
Usage Attribution
MUST READ: Before executing any gcloud, REST API, or MCP command, you
MUST read and follow Usage Attribution. Prefix
direct terminal gcloud calls (never generated scripts, Terraform, or user
code) with
CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:agent-platform-troubleshooting)"
and append agent-skills/1.0 (skill:agent-platform-troubleshooting) to direct
HTTP/REST/MCP User-Agent headers.
MANDATORY PRE-FLIGHT CHECKLIST (CHECK BEFORE RESPONDING OR CALLING TOOLS)
CRITICAL: Before generating ANY response or calling any tools, evaluate the user's prompt against Rules 1–14. When a Turn-0 rule matches, execute its directive immediately and STOP.
Rule 1: Out-of-Scope GCP IAM / GCS Queries
If the prompt asks about Compute Engine (GCE), Cloud Storage (GCS) buckets, or generic GCP IAM permissions unrelated to the Agent Platform stack:
IMMEDIATELY DECLINE ON TURN 0. DO NOT CALL ANY TOOLS OR GIVE IAM GUIDES.
Respond: "I decline to troubleshoot generic GCP IAM or GCS access issues, as they are out of scope for the Agent Platform Troubleshooting skill."
Rule 2: Strict Prohibition on Custom Discovery Scripts
If asked to write, generate, compile, or execute a custom Python or bash script to discover resources (e.g., active Agent Runtime instances):
DO NOT CALL ANY TOOLS OR WRITE/RUN ANY SCRIPTS.
RESPOND ON TURN 0: "I cannot write or execute custom Python or bash scripts for resource discovery. Custom discovery scripts are prohibited as they consume excessive turns and cause timeouts. Instead, use standard gcloud CLI commands (see Google Cloud SDK Installation) or curl REST API calls with application default credentials:
gcloud agent-registry agents list --location=us-central1orcurl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" "https://us-central1-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/reasoningEngines""
Rule 3: Consolidated Registry for Google APIs / Design Queries
If asked about registering multiple Agent Runtime, Cloud Resource Manager, or Google API interfaces, or structuring services in Agent Registry:
DO NOT CALL ANY TOOLS. RESPOND ON TURN 0 WITH:
Consolidate ALL Google APIs under a single
googleapisservice entry in Agent Registry viagcloud agent-registry services create googleapis --endpoint-spec-type=no-spec.Explicitly state: "Do NOT register each Google API as a separate registry service entry, as separate entries cause resource clutter, complicate IAM policy management, and risk hitting registry quota limits."
List all 8 required base FQDN interfaces (plus global
https://aiplatform.googleapis.comwhen calling global Gemini models):https://agentregistry.googleapis.comhttps://aiplatform.mtls.googleapis.comhttps://cloudresourcemanager.mtls.googleapis.comhttps://iamcredentials.mtls.googleapis.comhttps://telemetry.mtls.googleapis.comhttps://{region}-aiplatform.mtls.googleapis.comhttps://{region}-aiplatform.googleapis.comhttps://aiplatform.{region}.rep.googleapis.com
Refer to
references/agent-registry.md§2 for the full command.
Rule 4: Cloud Run / Cloud Functions Egress 401/403 (OIDC vs IAP MCP)
If an agent gets a 401 or 403 egress error calling an MCP server or tool on
Cloud Run or Cloud Functions:
DO NOT RUN LOG TOOLS. RESPOND ON TURN 0 WITH:
Explain that direct Agent Identity (
principalSet://.../principal://...) to standard Cloud Run OIDC authentication is not natively supported.Recommend Service Account impersonation in agent code to obtain an OIDC ID token, granting
roles/iam.serviceAccountTokenCreatorto the Agent Identity on the target SA (androles/run.invokerto that SA on Cloud Run).Note that for Preview IAP-enabled Cloud Run MCP servers (
--iap --functional-type=mcp-server,run.appshort URL), authorize via IAP/UAP instead ofroles/run.invoker(seereferences/known-issues.mdBKI 21 andreferences/agent-identity.md).
Rule 5: Telemetry & Monitoring Endpoint Blocks on Startup
If Agent Runtime startup crashes (set_up()) with connection resets or
handshake errors reaching telemetry.mtls.googleapis.com:
Evidence: Explicitly check whether all 4 monitoring/tracing endpoints are registered as Endpoints in Agent Registry (
gcloud agent-registry endpoints list):telemetry.mtls.googleapis.com,monitoring.googleapis.com,trace.mtls.googleapis.com, andcloudtrace.googleapis.com.Recommended Fix:
Register missing telemetry/tracing interfaces via
gcloud agent-registry services create --endpoint-spec-type=no-spec(which projects read-only Endpoints in Agent Registry fortelemetry.mtls.googleapis.com,monitoring.googleapis.com,trace.mtls.googleapis.com, andcloudtrace.googleapis.com).Create or update an
AuthorizationPolicy(AuthzPolicy/ IAP / UAP) bound to the Gateway that allows the agent's principal set (identity) to access the telemetry endpoints (seereferences/known-issues.mdBKI 23).
Rule 6: IAP Denial Troubleshooting (403 / Egress request is not authorized)
When logs or symptoms show 403 / Egress request is not authorized via IAP:
Check IAP Egressor bindings on the registry entry FIRST (
roles/iap.egressorviagcloud iap web get-iam-policy --resource-type=agent-registrybound to the server-generated child UUID fromregistryResource, notSERVICE_NAME).Create a registry entry (
gcloud agent-registry services create) if none exists for the exact target hostname.Grant
roles/iap.egressoron the registry entry (IAM v1 —set-iam-policyrequires top-level{"bindings": [...]}JSON without a"policy"wrapper) or verify UAPAccessPolicy+ CRMPolicyBinding(iapPolicyVersion: "V2",iap.googleapis.com/resources.egressViaIAP; seereferences/policies.md§2).Check IAP audit logs (
protoPayload.serviceName="iap.googleapis.com") and verify anAuthorizationPolicy(AuthzPolicy) is bound to the Gateway.Explicitly warn: "Do NOT use
roles/iap.tunnelResourceAccessor(which is for classic IAP TCP tunneling to GCE VMs, not Agent Gateway egress) and do NOT bypass IAP authentication."
Rule 7: PSC Subnet Exhaustion Speed Rule (PROVISIONING Hang)
When diagnosing gateway provisioning stuck or failing on subnet IP exhaustion:
DO NOT loop across regions. Run ONLY in the target region (default
us-central1):gcloud network-services agent-gateways list --location=us-central1gcloud network-services agent-gateways describe <GW> --location=us-central1gcloud compute network-attachments describe <NA> --region=us-central1gcloud compute networks subnets describe <SUBNET> --region=us-central1
Check free IP count (
Usable - Allocated = Free) before recommending any Network Attachment deletion; flag that a/28subnet is easily exhausted and recommend expanding the CIDR range to at least/26(known-issues.mdBKI 19).
Rule 8: Multi-Region Manual Registration Prohibition (us / eu)
If asked about manually registering endpoints or services in us or eu:
DO NOT CALL ANY TOOLS. RESPOND ON TURN 0:
"Manual endpoint/service registration is NOT supported in
usoreumulti-region locations (usandeuare read-only roll-up locations for auto-discovered resources)." (Explicitly name BOTHusandeu.)"Register manually in a specific region (e.g.,
us-central1) orglobal."
Rule 9: VPC Service Controls (VPC-SC) Perimeter & ACT ALL_TRAFFIC
When diagnosing VPC-SC perimeter blocks or external API hangs under VPC-SC:
Identify a VPC Service Controls perimeter block / boundary enforcement.
Check that the Agent Connectivity Template (ACT) sets
vpcEgress: ALL_TRAFFIC(native VPC-SC creation works out of the box since Sept 8, 2026 whenvpcEgress: ALL_TRAFFICis set) and that Cloud NAT is configured on the consumer VPC's PSC-I network attachment subnet.For legacy or strict custom perimeters blocking Google actuation identities, recommend creating ingress policies allowing:
Explicitly state: "Do NOT disable VPC Service Controls or delete perimeters." Refer to
references/known-issues.mdBKI 18 & 28.
Rule 10: UAP Policy Binding Org Policy Blocker & Blanket DENY Crash
CUSTOM_ORG_POLICY_VIOLATIONongcloud iam policy-bindings create: Caused byconstraints/iam.managed.disableAccessPolicyBinding(note: some docs misspell this plural). Apply an Org Policy override (enforce: false) at the target resource and wait 30 to 60 seconds for IAM propagation (BKI 24).Startup crash after UAP
destination.is_registered == falseDENY: Explain that the blanketDENYblocked internal/unauthenticated SDK bootstrap and metadata calls (such as Cloud Resource Manager project lookups) during Reasoning Engine init; remove or scope the blanketDENYrule (BKI 5).
Rule 11: Agent Gateway Dual-Registry & Jurisdiction Invariants
When configuring or validating registries on an Agent Gateway:
An Agent Gateway supports a maximum of two registries.
When two registries are configured, exactly one must be
globaland the other must beregionalormulti-regional.Binding two regional registries (e.g.,
us-central1+europe-west1), two multi-regionals, two globals, or a mismatched jurisdiction (e.g.,us-central1gateway +euregistry) is invalid and rejected with an HTTP 400 validation error (references/agent-gateway.md§4, BKI 26).
Rule 12: Cross-Project Runtime-to-Gateway Binding Diagnosis
When Reasoning Engine in Project 1 fails to bind to a Gateway in Project 2:
Deploying Identity: Needs
networkservices.agentGateways.useandnetworkservices.agentGateways.get(orroles/networkservices.viewer) in Project 2.Vertex AI Service Agent: Grant
roles/networkservices.vieweror custom roleae_agw_cross_project_sa(aliasar_agw_cross_project_sa) toservice-PROJECT_1_NUMBER@gcp-sa-aiplatform.iam.gserviceaccount.comin Project 2.Regional Colocation: Verify both runtime and gateway are in the same region.
CAA Opt-Out: Set
GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICEStoFalse(references/known-issues.mdBKI 10,references/agent-gateway.md§11).
Rule 13: Downstream SWP + PBR vs. Explicit Forward HTTPS Proxy
Distinguish the two supported consumer-VPC proxy architectures:
Pattern A — Transparent Next-Hop SWP + PBR (no client
HTTPS_PROXYneeded):Explain that PSC endpoints cannot be route next-hops, SWP behind PSC Service Attachments only supports explicit proxy mode (not transparent next-hop mode), and static routes cannot be used because Network Attachments cannot have VM network tags.
Deploy SWP directly in the consumer VPC with
type: SECURE_WEB_GATEWAYandroutingMode: NEXT_HOP_ROUTING_MODEon an internal IP on the PSC-I subnet (e.g.,10.20.1.250), with a/26REGIONAL_MANAGED_PROXYACTIVEsubnet.Configure Policy-Based Routing (PBR) matching source CIDR
10.20.1.0/24to--next-hop-ilb-ip=10.20.1.250(priority 200) + fallback PBR (1000).Create Cloud NAT with
ENDPOINT_TYPE_SWG(nats create ... --endpoint-types=ENDPOINT_TYPE_VM,ENDPOINT_TYPE_SWG), and allowlist<region>-aiplatform.mtls.googleapis.comin SWP CEL (BKI 33).
Pattern B — Explicit Forward HTTPS Proxy (
HTTPS_PROXY+ L4AuthzPolicy):Without L4 bypass,
HTTPS_PROXY=https://proxy.corp.internal:443fails onHTTP CONNECTwith HTTP404because Agent Gateway's L7 HTTP manager terminates TLS and rejects nestedCONNECT.Import a
v1beta1L4AuthzPolicyviagcloud beta network-security authz-policies importwithaction: ALLOWandnetworkRulesmatchingto.operations[].snis(omittarget.loadBalancingSchemeandports; max 5 rules; omitfromor include7.0.0.0/8+ PSC-I CIDR infrom.sources[].ipBlocks).Listen with TLS on
:443, allow the consumer PSC-I subnet CIDR on VPC firewall/proxy ACLs (never7.0.0.0/8), setNO_PROXY/no_proxyto.googleapis.com,googleapis.com,metadata.google.internal,169.254.169.254,localhost,127.0.0.1, bundleagentGatewayCard.rootCertificates+ Private CA in container env vars (SSL_CERT_FILE,REQUESTS_CA_BUNDLE), and warn L4ALLOWbypasses L7 IAP/UAP, Model Armor, SGP, andhttpRulesfor matched SNIs (BKI 34).
Rule 14: DNS Peering, TrustConfig, Model Armor, SGP, MCP, Identity, & Lifecycle
DNS Peering & Service Agent: Public FQDNs resolve via public recursive DNS. Private DNS requires
dnsPeeringConfig(domainsarray with trailing.; ACT uses stringtargetNetworkonly, whereas inlineAgentGateway.networkConfig.dnsPeeringConfigalso requirestargetProject). Cloud DNS caps total peering hops at 2 (Gateway consumes Hop 1 → max 1 consumer peering hop; a 2nd hop fails preflight or returnsSERVFAIL→503, BKI 35). Grantroles/dns.peer,roles/dns.reader,roles/compute.networkViewer, androles/compute.networkUsertoservice-GATEWAY_PROJECT_NUMBER@gcp-sa-agentgateway.iam.gserviceaccount.com(andcompute.networkAttachments.useto caller, BKI 9). Never use authoritative"."private root zones ("."requires a Cloud DNS Private Forwarding Zone).Private CA
TrustConfig& Immutable ACT: SetegressNetworkConfig.tlsConfig.trustConfigwithadditionalRoots: PUBLICLY_TRUSTED_ROOTS(omitting breaks*.googleapis.com). ACT fields are immutable — create a new ACT and rebind viaPATCHwithupdateMask=agentConnectivityTemplate(BKI 6).Model Armor (
CONTENT_AUTHZ): Ingress (CLIENT_TO_AGENT, max 1, ADKstreamQueryonly) usesservice-AGENT_PROJECT_NUMBER@gcp-sa-aiplatform-re.iam.gserviceaccount.com; Egress (AGENT_TO_ANYWHERE, max 4) usesservice-GATEWAY_PROJECT_NUMBER@gcp-sa-dep.iam.gserviceaccount.com. ScopehttpRuleswhento exclude gRPC and streams >60 seconds (Stream removed, BKI 13).Semantic Governance Policies (SGP): Uses
gcp-sa-aiplatform, non-streaming LLM calls only,.contains()+!request.headers['content-type'].startsWith('application/grpc')inwhen, and full-map updates onPATCH ?updateMask=metadatasosgpEnforcementMode: "DRY_RUN"andsgpUserIntentMatchingare preserved (BKI 38).Native MCP, Identity, Trace, & Teardown: Set
baseProtocolMethodsOption: MATCH_BASE_PROTOCOL_METHODSon MCPALLOWrules (BKI 39). Orgless trust domains useagents.global.proj-PROJECT_NUMBER.system.id.goog(proj-, neverproject-); never grantroles/aiplatform.expressUseror project-wideroles/aiplatform.userto Agent Identities. For Cloud Trace (TelemetryPolicy), always recommend enablingcloudtrace.googleapis.com(gcloud services enable cloudtrace.googleapis.com) and grantingroles/cloudtrace.agenttocompute-system,gcp-sa-networksecurity, andgcp-sa-agentgateway(seereferences/agent-gateway.md§8.3 andreferences/field-manual.mdStep 14.4). Tear down in strict 7-step order (workloads → UAP bindings →AuthzPolicy→ extensions →AgentGateway→ ACT → VPC) and use unique gateway IDs if deletion tombstones collide (BKIs 25, 30).
Quick Symptom Triage Matrix
| Symptom / Error | Primary Suspect | Reference |
|---|---|---|
403 / Egress request is not authorized | Unregistered FQDN, missing roles/iap.egressor / UAP binding, or PAB | Rules 4, 6; references/policies.md §2; BKIs 4, 7, 8, 15 |
HTTP 404 on HTTP CONNECT (HTTPS_PROXY) | Missing gcloud beta L4 AuthzPolicy (networkRules snis) | Rule 13B; references/agent-gateway.md §6.3; BKI 34 |
HTTP 498 immediately after binding runtime | Enforcing gateway bound before allowlisting essential platform APIs | references/agent-gateway.md §2; BKI 37 |
500 / PERMISSION_DENIED / Stream removed | Model Armor SA roles (gcp-sa-dep vs gcp-sa-aiplatform-re) or 60s stream cap | Rule 14; references/policies.md §12; BKI 13 |
503 / NXDOMAIN / SERVFAIL on private host | >2-hop DNS peering, authoritative "." zone, Packet Intercept, or SWP | Rules 13A, 14; references/agent-gateway.md §3, §6; BKIs 33, 35, 36 |
Config validation failed / PERMISSION_DENIED on import | Disabled agentregistry.googleapis.com, missing caller/gcp-sa-agentgateway IAM, or bad NA URI | Rule 14; BKIs 9, 20, 26 |
HTTP 409 ABORTED / 400 already being used | Active control-plane LRO mutex (~2 min), tombstone collision, or reverse teardown | references/agent-gateway.md §9, §10; BKIs 25, 29, 30 |
Startup crash (reasoning_engine_stderr) | Blocked telemetry/CRM bootstrap, UAP blanket DENY, or SGP gRPC interception | Rules 5, 10, 14; BKIs 1, 5, 17, 23, 38 |
When to use this skill
Trigger on Agent Gateway, Agent Connectivity Templates (ACT), Agent Registry,
Agent Identity, IAP/UAP policies, Model Armor, Semantic Governance Policies
(SGP), SWP/Explicit Proxy egress, Private CA TrustConfig, Cloud DNS peering,
Cloud Trace TelemetryPolicy, or Gemini Enterprise / Agent Runtime / GKE /
Cloud Run gateway bindings. Do not use for generic Google Cloud IAM, GCS,
GCE, or networking issues unrelated to the Agent Platform stack.
Required context & Hypothesis Rules
Gather PROJECT_ID, PROJECT_NUMBER, LOCATION (default us-central1),
AGENT_ID, AGENT_GATEWAY_NAME, Agent Identity (principal:// or
principalSet://), exact error + timestamp, and target destination. If missing,
ask or state unknowns using placeholders — never scan across projects or loop
over regions. Before Step 1 queries, formulate at most 3 hypotheses anchored
to "Why did it start failing now?" (e.g., recent Terraform/config changes).
Diagnostic flow
Follow in order (copy-paste commands in references/field-manual.md):
Step 0 — Pre-Flight & Access: Evaluate Rules 1–14. Verify project access (
gcloud projects describe $PROJECT_ID).Step 1 — Agent & Startup Logs: Classify error (
403,404 CONNECT,498,500,503, crash, timeout). Check PSC subnet IPs, ACTALL_TRAFFIC+ Cloud NAT, andagentGatewayCard.rootCertificatesCA trust.Step 2 — Gateway Logs: Query
networkservices.googleapis.com/Gateway(filtering-httpRequest.requestMethod="CONNECT"when inspecting L7 requests) to find the exact failing SNI/hostname andserviceExtensionsInfo.Step 3 — IAP / Model Armor / SGP Logs: Check
iapPolicyVersion(V1vsV2),DRY_RUNvs enforced, Model Armor callout status, orlogs/semantic-governance-policyverdicts and rationales.Step 4 — Registry State: Verify exact hostname permutations in
gcloud agent-registry {services,endpoints,mcp-servers,agents} listand confirm dual-registry + jurisdiction rules.Step 5 — Identity & Policies: Check
roles/iap.egressorvia--resource-type=agent-registryon the child UUID (V1), UAPAccessPolicy/PolicyBinding+constraints/iam.managed.disableAccessPolicyBinding(V2), PAB overrides, and least-privilege Agent Identity roles (proj-for orgless).Step 6 — AuthzPolicy & Extensions: Verify L4
networkRulesvs L7httpRules, MCPMATCH_BASE_PROTOCOL_METHODS, Model Armor / SGPwhenexclusions,ExtensionBindingscope, and policy caps (max 4 egress, max 1 ingressCONTENT_AUTHZ).Step 7 — Connectivity, DNS, & TLS: Verify ACT
TrustConfig(PUBLICLY_TRUSTED_ROOTS),gcp-sa-agentgatewayIAM, <=2 DNS peering hops, no Packet Intercept on the consumer VPC, and SWP/Explicit Proxy settings.Step 8 — PrincipalSet & Trace Verification: Test 1:1
principal://binding ifprincipalSet://lags; for Cloud Trace, enablecloudtrace.googleapis.com, verifyv1beta1TelemetryPolicy(telemetryTargetreferencingagentGateways/*and objectparentBasedSampling: {enabled: true, samplingRate: 1.0}, never stringENABLED), and grantroles/cloudtrace.agenttoservice-<PROJECT_NUMBER>@compute-system.iam.gserviceaccount.com,service-<PROJECT_NUMBER>@gcp-sa-networksecurity.iam.gserviceaccount.com, andservice-<PROJECT_NUMBER>@gcp-sa-agentgateway.iam.gserviceaccount.com.
Tools & Layered References
Use mcp__gcloud__run_gcloud_command (or gcloud --quiet),
mcp__gcloud-observability__list_log_entries (or gcloud logging read),
mcp__google-dev-knowledge__search_documents / get_documents / answer_query,
and curl REST GETs, plus bundled references (load only the smallest set needed):
references/field-manual.md — read first for operational commands & log queries
references/known-issues.md — BKIs #1–#13, #15–#39 for fast pattern matches
references/agent-gateway.md — topologies, ACT, DNS, TLS, SWP/Explicit Proxy, Trace, teardown
references/policies.md — L4/L7
AuthzPolicy, MCP, UAP v3beta, Model Armor, SGPreferences/agent-registry.md —
servicesvs projectedendpoints, 9 API families, jurisdictionsreferences/agent-identity.md — 3-identity delegation, Cloud Run OIDC vs IAP MCP, WIF
Output report
Always produce a read-only diagnostic report using this exact structure:
# Agent Platform Diagnostic — <one-line summary>
## Context
- Project: <id> (<number>) | Location: <region>
- Agent: <agent_id> | Gateway: <gateway_name>
- Symptom: <exact error message and when it started>
## Evidence gathered
- Agent log query: <filter, summary>
- Gateway log query: <filter, exact failing hostname / extension status>
- IAP / Policy log query: <filter, decision + enforcement mode>
- Registry & Policy state: <entries, AuthzPolicy bindings, roles/iap.egressor or UAP>
## Root cause hypothesis
<ranked root cause(s)>
## Why this fits the evidence
<connect log/config evidence to root cause>
## Recommended fix
<ordered gcloud / curl / YAML / Terraform changes for the user to apply>
## What to verify after the fix
<verification queries>
## Open questions / unknowns
<missing context or unverified items>
## Appendix: Raw Logs & Verified Links
- **Cloud Logging Filter**: <exact copy-pasteable filter or deep link>
- **Raw Logs**: <untruncated Agent, Gateway, and IAP/Policy log entries>Principles
Exact hostname match first: Compare gateway log hostnames directly against Agent Registry.
Layered default-deny: Registry → Gateway
AuthzPolicy→ Extension → IAP/UAP/Model Armor/SGP → PAB (PAB overrides IAM Allow).L4 bypass vs L7 governance: L4
networkRulesenablesHTTP CONNECTexplicit proxies (:443) but bypasses L7 IAP, Model Armor, and SGP for matched SNIs.Read-only, single-region, non-interactive: Pull evidence first, never mutate resources, check
us-central1unless logs indicate otherwise, and pass--quiet.
Supporting Links
Files
- ATTRIBUTION.mdAdded by AutoGineer878 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md26.2 KiB
- references/agent-gateway.md55.2 KiB
- references/agent-identity.md33.6 KiB
- references/agent-registry.md49.7 KiB
- references/attribution.md1.9 KiB
- references/field-manual.md68.3 KiB
- references/known-issues.md87.6 KiB
- references/policies.md75.2 KiB
references/field-manual.md
Field manual: Agent Gateway / Registry / Identity / IAP
Practical debugging knowledge for the Google Cloud Gemini Enterprise Agent Platform, distilled from real incident triage. Read this before diving into the official docs — it covers the gotchas that the docs don't surface.
Tip: Check Known Issues First: If the symptom matches a known pattern (e.g., startup failure, VPC-SC block, Cloud Run egress 403, explicit proxy 404, or DNS 2-hop
NXDOMAIN), jump straight toreferences/known-issues.md— it indexes recurring failure modes by symptom.
Table of Contents
The mental model: Lines 26-121
The single biggest gotcha: hostname permutations: Lines 122-153
Recommended Registry Structure: Consolidated Google APIs: Lines 154-191
Metric Queries & Visualization: Lines 192-228
Diagnostic playbook: Lines 229-1156
Steps 0–10: Core 403, Crash, PSC Exhaustion, ACT/NAT, UAP/IAM, Identity, Cross-Project, & Next-Hop SWP/PBR: Lines 270-1074
Step 11: Explicit HTTPS Proxy Egress (
HTTPS_PROXY+ L4networkRules): Lines 1075-1094Step 12: Cloud DNS Peering (2-Hop Limit) & Cross-Project Shared VPC IAM: Lines 1095-1122
Step 13: Private CA
TrustConfigTLS Failures & ACT Immutability: Lines 1123-1137Step 14: SGP, Model Armor 60s Stream Timeouts, Native MCP Rules, & Cloud Trace: Lines 1138-1156
Quick reference: the checks in order: Lines 1157-1179
The mental model
The Agent Platform runs as default-deny egress. An agent (typically an Agent Runtime instance) cannot talk to anything outside itself unless every layer permits it:
Agent Registry — the destination must be registered as an Endpoint, MCP Server, or Agent.
Agent Gateway — intercepts the request (it sits in front of the agent's egress). Note: an
authz_policymust explicitly target the gateway resource, otherwise the authz extension won't actually run.Service-extension (delegated authz) — the gateway calls IAP to make an allow/deny decision.
IAP / IAM Policy Evaluation — the agent's identity must be authorized by IAP:
IAM v1 (Legacy Policy Model): Evaluated when
iapPolicyVersion: "V1"(or unset). The agent identity must have the IAP egressor role (roles/iap.egressor, display name "IAP-secured Egressor") directly bound on the registered resource shadow resource in IAP.Unified Access Policy (UAP / Policy V2 / IAM v3): Evaluated when the gateway's IAP Authz Extension metadata specifies
iapPolicyVersion: "V2". Next-gen access control bound directly to Resource Manager hierarchy nodes (Organizations, Folders, Projects) viaPolicyBinding(iam.googleapis.com/v3). EvaluatesAccessPolicyrules with CEL expressions on deep attributes (destination.agent_registry.*ordestination.unregistered.*). Follows strict evaluation invariants: absolute DENY precedence (cannot be overridden by downstream projects), and additive ALLOW aggregation across the CRM tree.
Principal Access Boundary (PAB) — even with the IAM/UAP binding correct, a PAB policy on the principal set can restrict which resources it can reach. PAB takes precedence over IAM Allow — a correct egressor binding does nothing if a PAB scopes the principal away from the target.
Implementation note. Agent Gateway is built on a Google-managed Secure Web Proxy instance that provides the egress-proxy capabilities. Customers don't configure the proxy directly — its rules are derived from registry entries and authz policies. Denials can originate at this proxy layer before IAP runs (no IAP audit entry exists for those calls); those show up in load-balancer logs (see Step 3b).
Proxy Routing, TLS SNI & Agent Connectivity Templates (ACT): Inside an Agent
Runtime container, outbound connections enter the gateway tunnel via synthetic
PSC VIP CONNECT 240.0.0.2:443. By default, Agent Gateway terminates or inspects
TLS, evaluates the inner SNI hostname against Agent Registry and AuthzPolicy
rules, and resolves public internet and standard non-VPC-SC Google API hostnames
using public recursive DNS at the gateway proxy (Cloud DNS peering via
dnsPeeringConfig is required only for private internal domains such as
corp.internal. or VPC-SC googleapis.com. mapped to 199.36.153.4/30). If an
inner SNI hostname (e.g., us-central1-aiplatform.googleapis.com) is NOT
registered and no L4 networkRules policy matches, the proxy drops the request
with default_denied before IAP runs.
Under VPC Service Controls (VPC-SC), Agent Gateway requires an Agent
Connectivity Template (ACT) configured with vpcEgress: ALL_TRAFFIC:
Traffic destined for external public APIs (e.g.,
api.ipify.org,api.weather.gov) traverses the gateway and egresses through the consumer VPC PSC-I Network Attachment subnet via Cloud NAT using static IPs. If Cloud NAT is missing or misconfigured, external traffic hangs or resets silently.Traffic destined for Google APIs (e.g., Vertex AI, Cloud Run default domains
*.run.app) routes through Private Google Access / Restricted Google Access without traversing public Cloud NAT.
Don't confuse roles/iap.egressor with other IAP roles
The display name "IAP-secured Egressor" maps to roles/iap.egressor —
that's the role for Agent Gateway egress. Other IAP roles exist that are easy to
mistake for it but are unrelated:
| Role ID | Purpose | Use for Agent |
: : : Gateway? :
| :--------------------------------- | :----------------- | :----------------- |
| roles/iap.egressor | Agent egress | Yes — this one |
: : through Agent : :
: : Gateway : :
| roles/iap.tunnelResourceAccessor | TCP/SSH tunneling | No |
: : through IAP to a : :
: : VM : :
| roles/iap.httpsResourceAccessor | Access to | No |
: : IAP-protected web : :
: : apps (ingress) : :
| roles/iap.tunnelDestGroupUser | Member of an IAP | No |
: : tunnel destination : :
: : group : :
Don't substitute. The IAP authz check explicitly looks for
iap.webServiceVersions.egressViaIAP, which only roles/iap.egressor grants
for the Agent Gateway path.
If any layer says no, the agent gets back a 403:
{'code': 403, 'message': "403 Forbidden. {'message': 'Egress request is not authorized.', 'status': 'Forbidden'}"}The single biggest gotcha: hostname permutations
A Google API like aiplatform.googleapis.com is reachable through many
hostnames. The agent might call any of them depending on the SDK version,
regional client config, or whether mTLS is in play:
| Form | Example |
|---|---|
| Base | aiplatform.googleapis.com |
| Base + mTLS | aiplatform.mtls.googleapis.com |
| Locational | us-central1-aiplatform.googleapis.com |
| Locational + mTLS | us-central1-aiplatform.mtls.googleapis.com |
| Regional REP (public) | aiplatform.us-central1.rep.googleapis.com |
| Regional REP (private/PSC) | aiplatform.us-central1.p.rep.googleapis.com |
The gateway matches hostnames exactly. If you registered only
aiplatform.googleapis.com but the SDK actually called
us-central1-aiplatform.googleapis.com, the request gets denied — even though
"the API is registered." When investigating a 403, always establish what
hostname the agent actually called, then verify that exact hostname is in the
registry.
A registration script typically looks like this (note all five permutations):
reg_svc "${id}" "${name}" "https://${id}.googleapis.com"
reg_svc "${id}-mtls" "${name} mTLS" "https://${id}.mtls.googleapis.com"
reg_svc "${LOCATION}-${id}" "${name} Locational" "https://${LOCATION}-${id}.googleapis.com"
reg_svc "${LOCATION}-${id}-mtls" "${name} Locational mTLS" "https://${LOCATION}-${id}.mtls.googleapis.com"
reg_svc "${id}-${LOCATION}-rep" "${name} Regional (REP)" "https://${id}.${LOCATION}.rep.googleapis.com"Recommended Registry Structure: Consolidated Google APIs
To simplify management and reduce resource overhead, it is recommended to
register all Google APIs under a single googleapis service entry in the Agent
Registry using multiple interfaces (one for each required API hostname).
Recommended Base Interfaces (Consolidated googleapis Service)
Your base googleapis service should include the following interfaces:
https://agentregistry.googleapis.comhttps://aiplatform.mtls.googleapis.comhttps://cloudresourcemanager.mtls.googleapis.comhttps://iamcredentials.mtls.googleapis.comhttps://telemetry.mtls.googleapis.comhttps://{region}-aiplatform.mtls.googleapis.comhttps://{region}-aiplatform.googleapis.comhttps://aiplatform.{region}.rep.googleapis.com
(Replace {region} with your actual region, e.g., us-central1.)
Global-only foundation models &
.rep.mtlspitfall: When calling global-only Gemini models, also addhttps://aiplatform.googleapis.comto thegoogleapisservice. Never constructaiplatform.{us,eu}.rep.mtls.googleapis.comFQDNs (multi-region.rep.mtlsDNS records do not exist and fail withNXDOMAIN).
Other Services
If you are using additional Google Cloud APIs (or custom MCPs / separate engines), ensure their exact hostnames are included on the consolidated googleapis service (or registered as separate non-Google services):
discoveryengineloggingmonitoringoauth2cloudtraceandtraceiapmodelarmor
Missing any required API hostnames is the most common "agent works in dev, fails in prod" cause.
Metric Queries & Visualization
When diagnosing performance issues, latency spikes, or intermittent failures,
query and visualize relevant time-series metrics if you have monitoring access.
Note that the Google Cloud Console Agent Gateway Observability tab requires
upgrading the project's _Default log bucket to Log Analytics (_AllLogs view).
If the user reports "slowness" or "intermittent errors", visualize the trend
using a Mermaid xychart-beta chart in your diagnostic report.
1. Agent Gateway Egress QPS, Latency, & Error Rate
Query native Agent Gateway and underlying Secure Web Proxy metrics:
Metrics:
networkservices.googleapis.com/agentgateway/request_count,networkservices.googleapis.com/agentgateway/total_latencies,networkservices.googleapis.com/agentgateway/backend_latencies,networkservices.googleapis.com/agentgateway/iap_authz_request_count, andnetworkservices.googleapis.com/gateway/request_countBreakby:
response_code_class,gateway_name
2. Agent Runtime Latency (p50/p90/p99)
Query the Agent Runtime latency to identify performance degradation:
Metric:
aiplatform.googleapis.com/reasoning_engine/query_latencyBreakby:
reasoning_engine_id,location
3. Visualizing with Mermaid
When presenting latency or error trends in the report, format them as a Mermaid chart:
xychart-beta
title "Gateway Latency (p90) last 24h"
x-axis [00:00, 04:00, 08:00, 12:00, 16:00, 20:00]
y-axis "Latency (ms)" 0 --> 1000
line [120, 150, 850, 900, 140, 130]Diagnostic playbook
┌──────────────────────────────────────────────────────┐
│ 0. Establish context & Verify access │
└──────────────────────────┬───────────────────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ 1. Pull agent logs — classify primary symptom: │
│ • Timeout / Reset → 3c (PSC) & 3d (ACT / NAT) │
│ • Crash / Traceback → 1b (Runtime stderr / OOM) │
│ • 404 on HTTPS_PROXY → 11 (L4 networkRules SNI) │
│ • NXDOMAIN / Shared VPC → 12 (DNS 2-hop & Host IAM) │
│ • Private CA TLS Error → 13 (TrustConfig & Rebind) │
│ • 60s Cutoff / SGP /429 → 14 (SGP / MA / Trace) │
│ • 403 Forbidden → Continue to Step 2 │
└──────────────────────────┬───────────────────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ 2. Pull gateway logs — find EXACT hostname called │
└──────────────────────────┬───────────────────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ 3. Pull IAP logs — Check V1 vs V2, DRY_RUN, decision │
│ (If no IAP entry, check 3b proxy LB log) │
└──────────────────────────┬───────────────────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ 4. Is the EXACT hostname registered in Agent Registry│
│ (agents / mcp-servers / endpoints)? │
└────────────┬─────────────────────────────┬───────────┘
no │ yes │
▼ ▼
┌──────────────────────────┐ ┌──────────────────────────────┐
│ Unregistered hostname │ │ 5. Check IAM / UAP Policies │
│ permutation: register on │ │ 6. Authz extension & dual-reg│
│ consolidated googleapis │ │ 7. Agent Identity & PAB / CR │
│ or custom Service entry. │ │ 8–10. Principal, X-Proj, SWP │
└──────────────────────────┘ └──────────────────────────────┘Step 0 — Establish context & Disable prompts
Before running any diagnostics, ensure the gcloud CLI is installed (see Google Cloud SDK Installation), your environment is configured correctly, and prompts are disabled to prevent commands from hanging:
Disable CLI Prompts:
gcloud config set core/disable_prompts TrueVerify Project Access:
gcloud projects describe $PROJECT_IDIf this fails, you cannot proceed with log gathering. Prompt the user for correct permissions or coordinates.
Discover the Correct Project (if resources are missing): If the active project (configured in
gcloud) does not contain the expected Agent Gateways, Agent Runtime instances, or Registry entries, it may be the wrong project.Important: Check Active Project First: Always check the active project first before checking any other user-supplied project:
ACTIVE_PROJ=$(gcloud config get-value project) gcloud network-services agent-gateways list --location=us-central1 --project=$ACTIVE_PROJ gcloud agent-registry agents list --location=us-central1 --project=$ACTIVE_PROJIf you find the target resources in the active project, proceed immediately and do NOT check other projects.
If you cannot find the target resource (for example, the stuck gateway or the failing agent) in the active project:
Never write or execute custom Python or bash discovery scripts (or multi-project/multi-region
forloops) to scan across projects or regions. Use individualgcloudCLI commands (orcurlREST API calls authenticated withgcloud auth application-default print-access-token).Check at most 1–2 explicit candidate projects provided by the user in the target region (default
us-central1if unspecified):gcloud network-services agent-gateways list --location=us-central1 --project=$CANDIDATE_PROJECT_ID gcloud agent-registry agents list --location=us-central1 --project=$CANDIDATE_PROJECT_IDIf you cannot locate any candidate resource within 2 turns, stop searching and write the diagnostic report using clear placeholders for resource names while providing the complete verification commands and PSC subnet IP calculation formulas.
Once the project containing the resources is identified, use that
PROJECT_IDfor all subsequent steps.
Step 0.4 — Special Handling for Telemetry (telemetry.mtls.googleapis.com) Issues
If the symptom or error logs involve telemetry.mtls.googleapis.com (e.g.,
connection reset, handshake error, or certificate verify failed during
startup/set_up()):
This is a known issue that can be caused by Egress Gateway blocking (BKI 23) OR SSL CA trust issues (BKI 17).
In your diagnostic report, you MUST address both possibilities and unconditionally recommend the following actions (even if resources appear to be already configured in the dirty environment):
Verify/Perform Endpoint Registration: Explain that
telemetry.mtls.googleapis.commust be registered in the Agent Registry. You MUST also explicitly suggest checking whether other required monitoring/tracing endpoints (such asmonitoring.googleapis.comortrace.mtls.googleapis.com) are registered as Endpoints (gcloud agent-registry endpoints list --location=$LOCATION --project=$PROJECT_ID), and provide thegcloud agent-registry services createcommand (using--endpoint-spec-type=no-specand--interfaces=url=https://...,protocolBinding=JSONRPC) to register any missing endpoints.Verify/Create Authorization Policy: Explain that an
AuthorizationPolicymust allow the agent's principal set to access the telemetry endpoint (by binding aREQUEST_AUTHZpolicy with the IAP extension to the gateway). You MUST recommend creating or updating this policy and provide the exact gcloud/Terraform configuration for it, even if you see a policy already bound in the project.Verify CA Trust: Recommend configuring the agent's environment variables (
REQUESTS_CA_BUNDLE,SSL_CERT_FILE, andGRPC_DEFAULT_SSL_ROOTS_FILE_PATHpointing to/etc/ssl/certs/ca-certificates.crt) to ensure the Python/gRPC runtime trusts the gateway's TLS inspection CA.
Step 0.5 — Mismatched Symptoms (Dirty Environments)
In shared evaluation or development projects, the logs you retrieve might
contain errors from previous, unrelated runs (e.g., finding an SSL certificate verify failed error when the user is asking about IAP 403 errors).
If the logs you find do not match the symptom described in the user's prompt (e.g., the user complains about "403 errors... logs mention IAP" but you find "SSLError" and "no IAP logs"):
Do not ignore the user's prompt. Do not assume your log findings are the only issue.
In your diagnostic report, you MUST address the user's described symptom.
Explain that while you found a different error in the active logs (and diagnose it), for any logs or findings where the agent is getting a 403 to an MCP server or endpoint, you must check the IAP Egressor bindings on the matching resource in the registry first:
If there is no registry entry for the MCP server or endpoint, ensure there is one created.
Ensure that the agent has the
roles/iap.egressorrole bound to the registry entry. If there are no permissions matching, tell the user to grantroles/iap.egressoragainst the registry entry.Verify that an
AuthorizationPolicyis correctly bound to the Gateway.
Include these prioritized troubleshooting steps for IAP denials (checking registry entries and
roles/iap.egressorbindings first, checking IAP audit logs, and verifying Gateway policies) as recommended fixes, even if you couldn't verify them in the current log state.
Step 1 — Confirm the symptom in agent logs
Check the Agent Runtime logs for the error (403, SSL Handshake Timeout, or Connection Reset):
resource.type="aiplatform.googleapis.com/ReasoningEngine"
resource.labels.location=$LOCATION
resource.labels.reasoning_engine_id=$AGENT_ID
(textPayload:"403" OR textPayload:"handshake operation timed out" OR textPayload:"Connection reset by peer" OR textPayload:"Network is unreachable")Alternative (CLI Fallback):
# Note: --limit=10 limits output volume to capture recent error logs while preventing context overflow and command timeouts.
gcloud logging read 'resource.type="aiplatform.googleapis.com/ReasoningEngine" AND resource.labels.location="'$LOCATION'" AND resource.labels.reasoning_engine_id="'$AGENT_ID'" AND (textPayload:"403" OR textPayload:"handshake operation timed out" OR textPayload:"Connection reset by peer" OR textPayload:"Network is unreachable")' --project=$PROJECT_ID --limit=10The error payload tells you that it failed.
If it is a 403, continue with the standard Gateway/IAP flow (Step 2).
If it is an SSL Handshake Timeout or Connection Reset/Network Unreachable, suspect a PSC provisioning issue or subnet exhaustion. Skip to Step 3c.
If it is a container crash, startup error, or Python exception, proceed to Step 1b.
Step 1b — Debugging Agent Runtime Crashes (Container Crashes & Python Exceptions)
If the agent logs (Step 1) show that the Agent Runtime container failed to start or crashed during execution (instead of a 403 or network timeout), follow this checklist:
1. Pull stderr logs for Python exceptions
Query the stderr logs specifically to find traceback info:
resource.type="aiplatform.googleapis.com/ReasoningEngine"
resource.labels.location=$LOCATION
resource.labels.reasoning_engine_id=$AGENT_ID
logName="projects/$PROJECT_ID/logs/aiplatform.googleapis.com%2Freasoning_engine_stderr"Alternative (CLI Fallback):
# Note: --limit=20 fetches a sufficient recent log sample to identify startup stack traces without flooding output or timing out.
gcloud logging read 'resource.type="aiplatform.googleapis.com/ReasoningEngine" AND resource.labels.location="'$LOCATION'" AND resource.labels.reasoning_engine_id="'$AGENT_ID'" AND logName="projects/'$PROJECT_ID'/logs/aiplatform.googleapis.com%2Freasoning_engine_stderr"' --project=$PROJECT_ID --limit=20Look for common Python startup failures:
ModuleNotFoundErrororImportError: The uploaded agent code requires a package that was not specified in the deployment requirements.SyntaxError: Syntax error in the uploaded Python files.Initialization crashes in the
__init__method of the agent class.
2. Check for Resource Limit Exceeded (OOM)
If the container dies silently without a Python traceback, it may have been killed by the runtime due to Out of Memory (OOM) or CPU limits.
Check if the requested resource limits (CPU/Memory) in
DeploymentSpecare sufficient.Look for container termination status if visible in the logs (e.g., exit code
137usually indicates OOMKilled).
Step 2 — Find the failing hostname in gateway logs
resource.type="networkservices.googleapis.com/Gateway"
resource.labels.location="REGION"
resource.labels.gateway_name="AGENT_GATEWAY_NAME"Alternative (CLI Fallback):
# Retrieve recent gateway entries (exclude synthetic 240.0.0.2:443 CONNECT wrapper when inspecting inner L7 calls;
# omit the NOT clause if empty so pre-IAP default_denied routing drops remain visible):
gcloud logging read 'resource.type="networkservices.googleapis.com/Gateway" AND resource.labels.location="REGION" AND resource.labels.gateway_name="AGENT_GATEWAY_NAME" AND NOT jsonPayload.enforcedGatewaySecurityPolicy.hostname="240.0.0.2:443"' --project=PROJECT_ID --limit=50The gateway log entry shows the actual hostname the request targeted. Write it down — you will need it in Step 4.
Model Armor & SGP Special Cases (High-Confidence Indicators):
Model Armor
PERMISSION_DENIED(BKI 13): IfserviceExtensionInfoshowsgrpcStatus: "PERMISSION_DENIED"onmodelarmor.*, check gateway direction — Client-to-Agent ingress usesservice-${AGENT_PROJECT_NUMBER}@gcp-sa-aiplatform-re.iam.gserviceaccount.comwhereas Agent-to-Anywhere egress usesservice-${GATEWAY_PROJECT_NUMBER}@gcp-sa-dep.iam.gserviceaccount.com(seereferences/known-issues.mdBKI #13).Model Armor 60s Stream Cutoff (BKI 13 / Step 14): If
grpcStatusreportsUNKNOWN/DEADLINE_EXCEEDEDorStream removedright at 60 seconds, Envoy hit the non-configurable 60sCONTENT_AUTHZstream deadline.Semantic Governance Policy Denial (BKI 38 / Step 14): Query
logName="projects/PROJECT_ID/logs/semantic-governance-policy"for SGPjsonPayload.verdictandjsonPayload.evaluations[].rationale(note: streamed model calls return no verdict or an error).
Step 3 — Check IAP allow/deny decision
Important: Data Access Logs & API Prerequisite: IAP data-plane decisions are written to Data Access audit logs (
DATA_READtype, disabled by default), andiap.googleapis.commust be enabled in the gateway project (gcloud services list --enabled --filter="config.name:iap.googleapis.com" --project=$PROJECT_ID). Verify audit config with:gcloud projects get-iam-policy $PROJECT_ID \ --filter="auditConfigs.service:iap.googleapis.com" \ --format="yaml(auditConfigs)"If empty or missing
DATA_READforiap.googleapis.com, enable it in IAM → Audit Logs.
Query both UAP Policy V2 (iap.resources.egressViaIAP) and legacy IAM v1
(iap.webServiceVersions.egressViaIAP) while excluding MCP base-protocol noise:
protoPayload.serviceName="iap.googleapis.com"
(protoPayload.authorizationInfo.permission="iap.resources.egressViaIAP" OR protoPayload.authorizationInfo.permission="iap.webServiceVersions.egressViaIAP")
-protoPayload.metadata.mcp_attributes.base_protocol_method="true"Alternative (CLI Fallback):
gcloud logging read 'protoPayload.serviceName="iap.googleapis.com" AND (protoPayload.authorizationInfo.permission="iap.resources.egressViaIAP" OR protoPayload.authorizationInfo.permission="iap.webServiceVersions.egressViaIAP") AND -protoPayload.metadata.mcp_attributes.base_protocol_method="true"' --project=PROJECT_ID --limit=50What to read out of each entry:
protoPayload.authorizationInfo[].granted—trueorfalse.protoPayload.authenticationInfo.principalSubject— the SPIFFE /principal://...URI of the caller.protoPayload.authorizationInfo[].resource— the registered resource the call resolved to.labels."iap.googleapis.com/audited_resource_name"— if this isunregisteredResource, the destination hostname isn't in the registry. Go to Step 4.The policy version & enforcement mode — in
AuthzExtension(name,service, andtimeoutare all required onimport),iapPolicyVersionis uppercase"V2"(logged lowercase"v2"in audit logs):name: projects/PROJECT_ID/locations/LOCATION/authzExtensions/iap-authz-ext service: iap.googleapis.com failOpen: false timeout: 1s metadata: iamEnforcementMode: "DRY_RUN" # omit (or set "ENFORCE", never "ENFORCED") for active blocking iapPolicyVersion: "V2" # "V2" for UAP Policy V2; "V1" (or omit) for legacy IAM v1In
DRY_RUNmode, denials are logged but the request proceeds. If your agent fails with a real403while IAP is in dry-run, check the gateway proxy load-balancer log (Step 3b) or the destination backend.Under UAP (
iapPolicyVersion: "v2"), checkprotoPayload.metadata.policyEvaluationResults[]and audit log entries. UAP logs will display the evaluation outcomes across the Resource Manager hierarchy (Organization, Folder, Project).If an explicit DENY matched anywhere in the hierarchy (e.g., at Org or Folder level), the request is rejected immediately, even if a project-level policy allows it.
If no ALLOW matched, the request is denied by default-deny.
Check for CEL attribute mismatches (e.g., calling an unregistered host when policies only allow
destination.agent_registry.*, or path mismatches like missing.jsonextensions in REST API paths).
Step 3b — If there's no IAP audit entry for the failing call, pull the gateway proxy load-balancer log
The gateway's underlying egress proxy can deny a request before IAP runs. The
denial is in the proxy's load-balancer log. The SECURE_WEB_GATEWAY label here
refers to the proxy implementation under the hood:
jsonPayload.@type="type.googleapis.com/google.cloud.loadbalancing.type.LoadBalancerLogEntry"
resource.labels.gateway_type="SECURE_WEB_GATEWAY"Alternative (CLI Fallback):
# Note: --limit=50 limits output volume when querying load balancer log entries.
gcloud logging read 'jsonPayload.@type="type.googleapis.com/google.cloud.loadbalancing.type.LoadBalancerLogEntry" AND resource.labels.gateway_type="SECURE_WEB_GATEWAY"' --project=PROJECT_ID --limit=50Key fields to inspect:
httpRequest.status: Look for403.jsonPayload.enforcedGatewaySecurityPolicy.hostname: Look for240.0.0.2:443(expected under PSC).jsonPayload.enforcedGatewaySecurityPolicy.matchedRules: Look fordefault_denied.jsonPayload.mtls.clientCertChainVerified: Oftenfalseif connection dropped early.
If you see 240.0.0.2:443 under hostname and default_denied under
matchedRules, this is a routing drop. The proxy decrypted the tunnel but
failed to match the inner SNI hostname against the Agent Registry. Make sure
all required hostname permutations are registered.
Step 3c — Diagnosing PSC Subnet Exhaustion
If you observe SSL Handshake Timeouts or Connection Reset in the agent logs, or if the Agent Gateway deployment is failing/stuck, the Private Service Connect (PSC) subnet might be out of IP addresses.
Note: CLIENT_TO_AGENT Gateways: Both ingress (
CLIENT_TO_AGENT) and egress (AGENT_TO_ANYWHERE) gateways can be stuck in provisioning. Ingress gateways do NOT populate theagentGatewayCardeven when active, so check whether they are stuck by describing their network attachment and calculating subnet IPs.
Find the Agent Gateway Name (if not provided): List the gateways in the project to find the one that is stuck or relevant:
gcloud network-services agent-gateways list --location=$LOCATION --project=$PROJECT_IDIdentify the Network Attachment: Describe the Agent Gateway to find the Network Attachment in use:
gcloud network-services agent-gateways describe AGENT_GATEWAY_NAME --location=$LOCATION --project=$PROJECT_IDLook for
networkConfig.egress.networkAttachmentornetworkConfig.ingress.networkAttachment(depending on gateway type).Describe the Network Attachment:
gcloud compute network-attachments describe NETWORK_ATTACHMENT_NAME --region=$LOCATION --project=$PROJECT_IDNote the
subnetworkfield.Inspect the Subnet: Describe the subnet to check its IP range:
gcloud compute networks subnets describe SUBNET_NAME --region=$LOCATION --project=$PROJECT_IDCheck the
ipCidrRange(e.g., a/28subnet only has 16 IP addresses, and Google Cloud reserves 4, leaving only 12 for resources).Check IP Usage and Calculate Free IPs:
Find the number of allocated IPs by looking at the
connectionEndpointslist in the network attachment description from Step 2. Each endpoint in that list consumes one IP address.Calculate the number of usable IPs in the subnet based on its
ipCidrRange(e.g., a/28subnet has 16 IPs, minus 4 reserved by Google Cloud = 12 usable IPs; a/16has 65536 IPs, minus 4 = 65532 usable).Explicitly state the calculation in your report:
Usable IPs - Allocated IPs = Free IPs.Flag
/28Exhaustion Risk: Even if the current subnet has free IPs (or is larger, like/16), if you are diagnosing a stuck/failing gateway deployment, you MUST explicitly mention in your report that a/28subnet is too small and easily exhausted, and recommend expanding the CIDR range to at least/26as a best practice.
Step 3d — Diagnosing Agent Connectivity Template (ACT) & Network Routing
Under VPC Service Controls (VPC-SC), Agent Gateway relies on an Agent Connectivity Template (ACT). If the agent experiences timeouts, silent connection hangs, or connection drops when attempting to reach public internet endpoints or internal services, check the ACT and consumer network configuration:
Inspect the Agent Connectivity Template:
gcloud network-services agent-connectivity-templates describe ACT_NAME \ --location=$LOCATION --project=$PROJECT_IDVerify the
egressNetworkConfig.vpcEgressmode:vpcEgress: ALL_TRAFFIC: Routes all outbound traffic (public internet, SaaS APIs, internal RFC 1918, and Google APIs) through the consumer VPC Network Attachment. Mandatory for VPC Service Controls (VPC-SC).vpcEgress: PRIVATE_RANGES_ONLY: Routes only private/restricted ranges (RFC 1918, RFC 6598100.64.0.0/10, Class E240.0.0.0/4,private.googleapis.com199.36.153.8/30, andrestricted.googleapis.com199.36.153.4/30) into the consumer VPC; standard Google APIs use Private Google Access and public internet traffic egresses directly from Agent Gateway.
Verify Consumer Cloud NAT for External Endpoints (BKI 28): When
vpcEgress: ALL_TRAFFICis enabled, external internet traffic (e.g.,api.ipify.org,api.weather.gov, third-party SaaS) traverses the gateway and exits through the consumer VPC PSC-I Network Attachment subnet.Cloud NAT Requirement: The consumer VPC MUST have a Cloud NAT gateway covering the PSC-I subnet range (with Private Google Access enabled on the subnet).
If Cloud NAT is missing or does not cover the PSC-I subnet, TCP connections to external internet endpoints hang silently or reset without a proxy error log.
Verify NAT status:
gcloud compute routers nats list --router=$ROUTER_NAME --region=$LOCATION --project=$PROJECT_ID
Verify Cloud DNS Peering Scope (See Step 12): Agent Gateway resolves public internet domains and non-VPC-SC Google APIs via public recursive DNS at the gateway proxy without Cloud DNS peering.
dnsPeeringConfigis required only for private internal domains (e.g.,corp.internal.) or when enforcing VPC-SC (googleapis.com.mapped torestricted.googleapis.com199.36.153.4/30or internal PSC endpoints).Ordered 7-Step Teardown & Dangling ACT References (BKI 30): Always delete resources in strict dependency order, polling each async operation to
404before proceeding:Delete or unbind
ReasoningEngineinstances (?force=trueon RESTDELETEif active sessions/memories exist).Delete UAP
PolicyBindingthenAccessPolicy(gcloud iam policy-bindings delete→ poll404→gcloud iam access-policies delete).Delete
AuthzPolicy,TelemetryPolicy, andExtensionBindingresources targeting the gateway.Delete
AuthzExtensionresources.Delete
AgentGatewayand pollgcloud network-services agent-gateways describeuntilNOT_FOUND(404).Delete
AgentConnectivityTemplate(gcloud network-services agent-connectivity-templates delete),TrustConfig, andNetworkAttachment.Delete consumer Cloud NAT, subnets, and VPC.
If
AgentConnectivityTemplatedeletion still fails withFAILED_PRECONDITION: Resource ... is already being used by resource(s) .../agentGateways/...after Step 5 confirmed404and async producer cleanup has settled, unblock deployments immediately by creating a newly namedAgentConnectivityTemplateand open a Google Cloud Support case citing the stuckagentConnectivityTemplatesURI to purge the orphaned producer reference.
Step 4 — Verify the hostname is registered (in the form the agent used)
List registry entries — pick the right resource type for the destination:
gcloud agent-registry endpoints list --project=$PROJECT_ID --location=$LOCATION
gcloud agent-registry mcp-servers list --project=$PROJECT_ID --location=$LOCATION
gcloud agent-registry agents list --project=$PROJECT_ID --location=$LOCATIONGrep the output for the exact hostname from step 2. If it's missing, that's the root cause.
Step 5 — Verify IAM / UAP bindings on the registered resource
Depending on whether your gateway uses IAM v1 or Unified Access Policy
(UAP / Policy V2) (determined by iapPolicyVersion in the Authz Extension),
verify the corresponding authorization bindings:
Option A: Unified Access Policy (UAP / Policy V2 / IAM v3)
In UAP, access policies are bound directly to the Google Cloud Resource Manager (CRM) hierarchy (Project, Folder, or Organization) rather than IAP shadow resources.
Search Policy Bindings Attached to the Target Project:
# List bindings owned by the project (note: `list` has NO --target flag) gcloud iam policy-bindings list --project="${PROJECT_ID}" --location=global # Search bindings targeting the project's CRM node gcloud iam policy-bindings search-target-policy-bindings \ --target="//cloudresourcemanager.googleapis.com/projects/${PROJECT_NUMBER}" \ --project="${PROJECT_ID}" \ --location=globalSearch Policy Bindings on Parent Folders / Organization:
# Folder level gcloud iam policy-bindings search-target-policy-bindings \ --target="//cloudresourcemanager.googleapis.com/folders/${FOLDER_ID}" \ --project="${PROJECT_ID}" \ --location=global # Organization level gcloud iam policy-bindings search-target-policy-bindings \ --target="//cloudresourcemanager.googleapis.com/organizations/${ORGANIZATION_ID}" \ --project="${PROJECT_ID}" \ --location=globalInspect the Referenced AccessPolicy:
gcloud iam access-policies describe ACCESS_POLICY_ID \ --project="${PROJECT_ID}" \ --location=globalVerify the rule uses the full FQDN permission:
iap.googleapis.com/resources.egressViaIAP.Verify the agent's principal or principal set matches
rules[].principals(watch for orglessproj-${PROJECT_NUMBER}, neverproject-).Inspect CEL conditions: check for null dereferences (
mcp_server.method == 'tools'), unsupported.startsWith()/.matches()onagent_registry.*, missing.jsonextensions in unregistered REST API paths, or blanketdestination.is_registered == falseDENYrules that crash container boot.
Check for Org Policy Constraint Blockers (BKI 24): If
gcloud iam policy-bindings createfailed withCUSTOM_ORG_POLICY_VIOLATION, check whetherconstraints/iam.managed.disableAccessPolicyBindingis enforced:gcloud org-policies describe constraints/iam.managed.disableAccessPolicyBinding --project=$PROJECT_IDTo unblock, apply an override disabling the constraint (
enforce: false). Note: IAM access policies, bindings, and Org Policy overrides take ~30 to 60 seconds to propagate.REST API Fallback for UAP Bindings:
curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ "https://iam.googleapis.com/v3/projects/${PROJECT_ID}/locations/global/policyBindings"
Option B: IAM v1 (Legacy Policy Model)
In IAM v1, roles/iap.egressor is bound directly to the IAP shadow resource at
the registry or endpoint level:
Registry-level IAM policy
curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-d '{}' \
-X POST "https://iap.googleapis.com/v1/projects/${PROJECT_NUMBER}/locations/${LOCATION}/iap_web/agentRegistry:getIamPolicy" \
-H "Content-Type: application/json"Per-endpoint IAM policy
curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-d '{}' \
-X POST "https://iap.googleapis.com/v1/projects/${PROJECT_NUMBER}/locations/${LOCATION}/iap_web/agentRegistry/endpoints/${ENDPOINT_ID}:getIamPolicy" \
-H "Content-Type: application/json"Same call, but for global registry:
curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-d '{"options": {"requestedPolicyVersion": 3}}' \
-X POST "https://iap.googleapis.com/v1/projects/${PROJECT_NUMBER}/locations/global/iap_web/agentRegistry:getIamPolicy" \
-H "Content-Type: application/json"When reading the returned policy, look for a binding that matches the agent's
service account or principal set with role roles/iap.egressor.
Step 6 — Inspect the gateway / authz extension wiring
List authz extensions
gcloud service-extensions authz-extensions list \
--location=$LOCATION --project=$PROJECT_ID
gcloud service-extensions authz-extensions describe RESOURCE_NAME \
--location=$LOCATION --project=$PROJECT_IDVerify AuthorizationPolicy & AuthzExtension Wiring
Check
iapPolicyVersionin Authz Extension: Describe the Authz Extension and inspect themetadatamap:gcloud service-extensions authz-extensions describe RESOURCE_NAME \ --location=$LOCATION --project=$PROJECT_ID --format="yaml(metadata)"If using UAP (Policy V2):
iapPolicyVersionMUST be explicitly set to"V2".If using IAM v1:
iapPolicyVersionis"V1"or unset.Check
iamEnforcementMode:"DRY_RUN"logs evaluations without blocking; omittingiamEnforcementMode(or setting"ENFORCE", never"ENFORCED") actively blocks.
Verify AuthorizationPolicy Binding: Verify that the
AuthorizationPolicyis correctly bound to yourGateway(and omitstarget.loadBalancingSchemewhen targetingagentGateways/*). If it is not bound, the authorization logic will not run on gateway traffic.Inspect the
AuthorizationPolicyresource.Ensure the policy's target matches the gateway's name and location.
Verify Multi-Registry Gateway Constraints (BKI 26): Inspect the Agent Gateway description:
gcloud network-services agent-gateways describe AGENT_GATEWAY_NAME \ --location=$LOCATION --project=$PROJECT_ID --format="yaml(registries)"Network Services permits at most 2 registries bound to an Agent Gateway.
When 2 registries are configured, exactly ONE must be
globaland the second must beregional(same region as gateway) ormulti-regional(same jurisdiction, e.g.,us-central1+us).Configuring two regional, two multi-regional, two global, or cross-jurisdiction registries is rejected with HTTP
400/InvalidArgument.
List authz policies, agent gateways, and authz extensions via raw API
# authzPolicies (use v1beta1 if inspecting L4 networkRules; v1 for GA httpRules/CUSTOM)
curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
"https://networksecurity.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/authzPolicies"
# agentGateways
curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
"https://networkservices.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/agentGateways"
# authzExtensions (hosted under networkservices.googleapis.com, NOT serviceextensions.googleapis.com)
curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
"https://networkservices.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/authzExtensions"Step 7 — Verify the agent identity has the baseline roles
The agent identity itself needs least-privilege baseline permissions on the source side:
Least-privilege check (
agentDefaultAccess&agentInvoker): Deployed Agent Identities automatically receiveroles/aiplatform.agentDefaultAccessandroles/aiplatform.agentContextEditor. Do NOT grant project-levelroles/aiplatform.userorroles/aiplatform.expressUserto an Agent Identity (they allow modifying/deleting siblingReasoningEngineinstances); for A2A calls, bind a customagentInvokerrole (aiplatform.reasoningEngines.{query,get}) on the target engine only.roles/agentregistry.viewer— to discover registered catalog entries and validate gateway bindingsroles/logging.logWriter,roles/monitoring.metricWriter, telemetry roles — observabilityroles/browser— needed forresourcemanager.projects.getduring SDK init. Without it, the ReasoningEngine fails startup withFailed to convert project number to project ID(see known-issues §1).roles/iap.httpsGatewayUser(IAP-secured Web App User) androles/iap.egressor(IAP-secured Egressor) — to ensure the agent is authorized to egress through IAP. You MUST recommend verifying both roles and the AuthorizationPolicy binding in your report's fix/debugging section:roles/iap.httpsGatewayUseris typically required on the Gateway resource.roles/iap.egressoris required on the target Registry/Endpoint.Verify that the
AuthorizationPolicyis correctly bound to the Gateway (ensure the policy targets the gateway resource). Do NOT omit these recommendations even if you believe they are already correctly configured, as they are essential verification steps for the user.
Step 7b — Check Principal Access Boundary (PAB) policies
A PAB policy can override IAM Allow and restrict the resources the principal set can reach.
# List org-wide PAB policies
gcloud iam principal-access-boundary-policies list \
--organization="${ORGANIZATION_ID}" --location=global
# Inspect policy bindings attached to the project resource
gcloud iam policy-bindings search-target-policy-bindings \
--location=global \
--project="${PROJECT_ID}" \
--target="//cloudresourcemanager.googleapis.com/projects/${PROJECT_NUMBER}"Step 7c — Cloud Run / Functions Egress Authentication
If the destination is Cloud Run or Cloud Functions, direct OIDC authentication
using the default Agent Identity (principalSet://...) is not natively
supported by Cloud Run. The agent must use Service Account impersonation.
You MUST recommend the following in your report if the destination is Cloud Run:
Explain that direct Agent Identity to Cloud Run OIDC auth is unsupported.
Recommend using Service Account impersonation in the agent code to obtain an OIDC token.
Specify that the Agent Identity needs
roles/iam.serviceAccountTokenCreatoron the target Service Account (which in turn needsroles/run.invokeron the Cloud Run service). Refer toreferences/known-issues.mdBKI 21 for details and code examples.
Step 8 — PrincipalSet vs Principal
If permissions seem flaky, suspect the PrincipalSet binding. Move to a 1:1 Principal binding (bind the specific service account directly) to verify.
Step 9 — Cross-Project Runtime-to-Gateway Binding Verification
When an Agent Runtime (Reasoning Engine) in Project A (AE_PROJECT_NUMBER)
binds to an Agent Gateway in Centralized Governance Project B
(AGW_PROJECT_ID):
Check Deployer Caller Permissions: Verify the deploying identity has
roles/networkservices.viewer(ornetworkservices.agentGateways.getandnetworkservices.agentGateways.use) on the gateway in Project B:gcloud network-services agent-gateways describe GATEWAY_NAME \ --project=AGW_PROJECT_ID \ --location=REGIONCheck Vertex AI Service Agent IAM in Gateway Project: Ensure Project A's service agent is authorized in Project B:
gcloud projects get-iam-policy AGW_PROJECT_ID \ --flatten="bindings[].members" \ --filter="bindings.members:service-AE_PROJECT_NUMBER@gcp-sa-aiplatform.iam.gserviceaccount.com" \ --format="table(bindings.role)"Must have
roles/networkservices.vieweror custom roleae_agw_cross_project_sa(networkservices.agentGateways.get,networkservices.operations.get).Validate Regional Colocation Invariant: Both the runtime and the gateway MUST be deployed in the exact same region (e.g.
us-central1). Cross-region bindings fail control plane validation withINVALID_ARGUMENT.Verify Context-Aware Access (CAA) Token Sharing Opt-Out: Verify that the agent runtime was deployed with:
"GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES": FalseWithout this, bound token enforcement drops credentials during cross-project egress, returning401 Context-Aware Access requirements are not met.Validate IAP Policy Target (Server-Generated Resource ID vs. Friendly Name): Ensure IAP policies (
gcloud iap web add-iam-policy-binding --resource-type=agent-registry) target the server-generated resource ID (agentregistry-00000000-...extracted viaregistryResource), NOT the friendly service name:gcloud agent-registry services describe MCP_SERVICE_NAME \ --project=AGW_PROJECT_ID \ --location=REGION \ --format='value(registryResource)'Verify Cross-Project VPC Service Controls (VPC-SC): If Project A and Project B are in separate perimeters, ensure a perimeter bridge or ingress/egress rules cover
aiplatform.googleapis.com,networkservices.googleapis.com, andagentregistry.googleapis.com.
Step 10 — Diagnose Secure Web Proxy (SWP) and Policy-Based Routing (PBR) Egress
Note: Pattern A (Transparent Next-Hop SWP + PBR — This Step) preserves full Agent Gateway L7 governance (IAP/UAP, Model Armor, SGP) before VPC next-hop inspection. If your Agent Runtime container instead sets
HTTPS_PROXY=https://proxy.corp.internal:443to tunnel through an explicit forward proxy via L4networkRules, jump to Step 11.
If the consumer VPC employs a downstream Secure Web Proxy (SWP) behind an Agent Gateway Network Attachment for Layer 7 inspection:
Verify Next-Hop SWP Deployment Mode: Confirm SWP is deployed directly in the consumer VPC with
type: SECURE_WEB_GATEWAYandroutingMode: NEXT_HOP_ROUTING_MODE. Do NOT attempt to use PSC Service Attachments (which only support explicitHTTP CONNECTproxies) or static routes (which fail because Network Attachments cannot bear VM instance tags).Verify Policy-Based Routing (PBR) Matching: Ensure a PBR exists with priority 200 matching source CIDR of the PSC-I subnet (
10.20.1.0/24) and destination0.0.0.0/0routing to--next-hop-ilb-ip=<SWP_IP>:gcloud network-connectivity policy-based-routes create agw-psci-to-swp-pbr \ --network=projects/PROJECT_ID/global/networks/VPC_NAME \ --source-range=10.20.1.0/24 \ --destination-range=0.0.0.0/0 \ --next-hop-ilb-ip=10.20.1.250 \ --priority=200 \ --project=PROJECT_IDEnsure a default fallback PBR exists with priority 1000 routing to
DEFAULT_ROUTING.Verify Cloud NAT
ENDPOINT_TYPE_SWGon Proxy Subnet: Ensure the Cloud NAT covering the proxy-only subnet (REGIONAL_MANAGED_PROXY) includes--endpoint-types=ENDPOINT_TYPE_VM,ENDPOINT_TYPE_SWG. Without this, SWP proxy backends cannot establish outbound connections to the internet.Verify GatewaySecurityPolicy CEL Allowlist: Check SWP logs for
DENIEDdecisions undernetworkservices.googleapis.com/Gateway. Verify that both external target domains and the regional AI Platform session endpoint (<region>-aiplatform.mtls.googleapis.com) are allowed in CEL rules:inUrlList(host(), ['api.weather.gov', 'api.ipify.org', 'REGION-aiplatform.mtls.googleapis.com'])Omission of the regional AI Platform endpoint breaks ADK streaming queries with HTTP 503 (
remote connection failure).
Step 11 — Diagnose Explicit HTTPS Proxy Egress (HTTPS_PROXY + L4 networkRules)
When an Agent Runtime container is configured with HTTPS_PROXY=https://proxy.corp.internal:443 (explicit forward proxy over TLS) instead of transparent Next-Hop SWP:
Diagnose
HTTP 404 Not Found(CONNECT tunnel failed, response 404):Cause: Agent Gateway's default L7 listener terminates outer TLS and rejects nested
HTTP CONNECTrequests with404when no L4networkRulespolicy matches the proxy's SNI (or when the proxy listens on plaintext HTTP instead of TLS:443, or:443was omitted fromHTTPS_PROXY).Verify L4
AuthzPolicy(v1beta1) & Consumer Proxy ACLs: Confirm anAuthzPolicywithaction: ALLOWandnetworkRulesmatching the proxy's exact SNI is imported viagcloud beta(GAgcloudrejectsnetworkRules), omitstarget.loadBalancingScheme, omitsports, and either omitsfromor includes7.0.0.0/8+ PSC-I CIDR infrom.sources[].ipBlocks(while consumer VPC firewall/Squid ACLs allow only the consumer PSC-I subnet CIDR, never7.0.0.0/8):gcloud beta network-security authz-policies describe ALLOW_PROXY_POLICY_NAME \ --location=$LOCATION --project=$PROJECT_ID
Verify
NO_PROXY/no_proxyExclusions (Prevent Control-Plane Hair-Pinning):Inspect the Reasoning Engine's
deploymentSpec.envand verifyNO_PROXYandno_proxyexclude metadata and (where direct Google API routing is desired) Google APIs:169.254.169.254,metadata.google.internal,localhost,127.0.0.1,.googleapis.com,googleapis.comMissing
NO_PROXYroutes metadata or Vertex AI session/telemetry calls into the external corporate proxy, causing boot hangs or403authentication failures.
Verify Container-Side Private CA Trust:
ACT
tlsConfig.trustConfigdoes not apply to L4-bypassedloopback_tls_network_authztunnels. If the explicit proxy uses a private CA or performs TLS inspection, bundle both the proxy CA and system roots inside the agent container (SSL_CERT_FILE,REQUESTS_CA_BUNDLE,GRPC_DEFAULT_SSL_ROOTS_FILE_PATH).
Account for the L7 Governance Trade-Off:
Matching an L4
networkRulesALLOWrule bypasses L7 TLS termination at Agent Gateway, skipping IAP/UAP, Model Armor, SGP, and L7httpRuleson traffic inside that proxy tunnel. Use Step 10 (Next-Hop SWP + PBR) if both Agent Gateway L7 governance and downstream VPC proxy inspection are required.
Step 12 — Diagnose Cloud DNS Peering (2-Hop Limit) & Cross-Project Shared VPC IAM
When private hostnames fail with NXDOMAIN / 503 or gateway/ACT creation fails with PERMISSION_DENIED, INVALID_ARGUMENT, or Code 13:
Inspect
AgentConnectivityTemplatednsPeeringConfig:gcloud network-services agent-connectivity-templates describe $ACT_NAME \ --location=$LOCATION --project=$PROJECT_ID --format="yaml(egressNetworkConfig)"Every entry in
dnsPeeringConfig.domains[]must end with a trailing dot (e.g.,corp.internal.,googleapis.com.).dnsPeeringConfig.targetNetworkis a single string URI (projects/TARGET_VPC_PROJECT_ID/global/networks/VPC_NAME) using the Project ID (not project number). VerifynetworkAttachment's subnet belongs to the expected VPC (or a region supporting decoupled hubtargetNetwork).
Check the 2-Hop Transitive DNS Peering Limit & Root
"."Zone Trap:gcloud dns managed-zones list --project=$TARGET_VPC_PROJECT_ID \ --format="table(name,dnsName,visibility,peeringConfig.targetNetwork.networkUrl,forwardingConfig)"2-Hop Limit: Agent Gateway's tenant peering zone consumes Hop 1 (
Tenant VPC → Attached Spoke VPC). If the Attached Spoke VPC uses a Cloud DNS Peering Zone (Hop 2) pointing to a Central Hub VPC, the Central Hub VPC MUST host an Authoritative Private Zone (or resolve locally). Chaining to a third DNS Peering Zone returnsNXDOMAIN/SERVFAIL(503).Root
"."Domain Trap: Peering"."works only with a Cloud DNS Private Forwarding Zone pointing to an upstream recursive resolver. Configuring an Authoritative Private Zone for"."breaks all public internet and*.googleapis.comresolution withNXDOMAIN.
Verify Dual-Principal Cross-Project / Shared VPC IAM on
TARGET_VPC_PROJECT_ID:Caller / Provisioning Identity: Needs
roles/compute.networkViewer,roles/dns.reader,roles/networkconnectivity.regionalEndpointAdmin, androles/networkconnectivity.consumerNetworkAdmin(orroles/viewer) on the host project, pluscompute.networkAttachments.use(roles/compute.networkUser) when referencing a host-project attachment.Agent Gateway Service Agent (
service-${AGW_PROJECT_NUMBER}@gcp-sa-agentgateway.iam.gserviceaccount.com): Needsroles/dns.peer,roles/dns.reader, androles/compute.networkViewerplusroles/compute.networkUser(when Network Attachment is in the service project, recommended) ORroles/compute.networkAdmin(when Network Attachment is in the host project):gcloud projects get-iam-policy $TARGET_VPC_PROJECT_ID \ --flatten="bindings[].members" \ --filter="bindings.members:service-${AGW_PROJECT_NUMBER}@gcp-sa-agentgateway.iam.gserviceaccount.com" \ --format="table(bindings.role)"
Step 13 — Diagnose Private CA TrustConfig TLS Failures & ACT Immutability
When private HTTPS destinations or *.googleapis.com calls fail TLS verification after attaching a Certificate Manager TrustConfig:
Inspect
TrustConfig&additionalRoots:gcloud certificate-manager trust-configs describe $TRUST_CONFIG_NAME \ --location=$LOCATION --project=$PROJECT_IDConfirm the
TrustConfigis in the exact same project and region as the Agent Gateway andAgentConnectivityTemplate, and that target server certificates include a Subject Alternative Name (SAN) matching the hostname.*.googleapis.comBreakage (PUBLICLY_TRUSTED_ROOTS): CheckegressNetworkConfig.tlsConfig.additionalRootson the ACT. If set toNO_ADDITIONAL_ROOTS, Agent Gateway rejects Google-signed certificates for*.googleapis.comand all public HTTPS APIs! SetadditionalRoots: PUBLICLY_TRUSTED_ROOTS.
Apply Updates via New ACT + Gateway Rebind (Immutability Rule):
tlsConfig.trustConfigis immutable on an existingAgentConnectivityTemplate, and attached Agent Gateways do not pick up in-placetlsConfigedits.Fix: Create a new
AgentConnectivityTemplate(e.g.,act-v2) referencing the samenetworkAttachmentwith the correctedtlsConfig, then re-import/update theAgentGatewayYAML to pointagentConnectivityTemplatetoact-v2.
Step 14 — Diagnose SGP, Model Armor 60s Stream Timeouts, Native MCP Rules, & Cloud Trace
Semantic Governance Policies (SGP):
Query SGP data-plane evaluation logs (
verdict,evaluations[].rationale,token_usage):gcloud logging read 'logName="projects/'$PROJECT_ID'/logs/semantic-governance-policy"' \ --project=$PROJECT_ID --limit=20If streamed model calls (
:streamGenerateContent,:streamRawPredict) return no verdict or an error (or produce zero entries inlogs/semantic-governance-policy), invoke models without streaming and verify theCONTENT_AUTHZAuthzPolicyincludes the non-streamingwhenCEL filter using.contains()(:generateContent,:rawPredict,/v1/messages,/chat/completions) while excludingapplication/grpc(unexcluded gRPC crashes startup).If SGP unexpectedly began blocking in staging, inspect
gcloud service-extensions authz-extensions describe $EXT_NAME --location=$LOCATION --project=$PROJECT_ID --format="yaml(metadata)"— updatingsgpUserIntentMatchingreplaces the entiremetadatamap and wipessgpEnforcementMode: "DRY_RUN"if omitted.If SGP policy/engine CLI commands return
SEMANTIC_GOVERNANCE_POLICY_AGENT_NOT_CONFIGUREDorSEMANTIC_GOVERNANCE_POLICY_ENGINE_NOT_ENABLED_IN_REGION, confirm the Reasoning Engine was created withAGENT_IDENTITY+agent_gateway_config,service-${PROJECT_NUMBER}@gcp-sa-aiplatform.iam.gserviceaccount.comhasroles/compute.networkAdminandroles/dns.admin, consumer VPC subnets avoid10.0.0.0/24–10.0.2.0/24, and the engine isACTIVE(with ACT DNS peering resolvingdnsRecord).
Model Armor (
CONTENT_AUTHZ)PERMISSION_DENIEDvs. 60sStream removed:PERMISSION_DENIED(BKI 13): Check gateway direction! Client-to-Agent (ingress) requiresroles/modelarmor.calloutUser(agent project) +roles/modelarmor.user(template project) onservice-${AGENT_PROJECT_NUMBER}@gcp-sa-aiplatform-re.iam.gserviceaccount.com(and sanitizes only ADKstreamQuery). Agent-to-Anywhere (egress) requiresroles/modelarmor.calloutUser+roles/serviceusage.serviceUsageConsumer(gateway project) +roles/modelarmor.user(template project) onservice-${GATEWAY_PROJECT_NUMBER}@gcp-sa-dep.iam.gserviceaccount.com.500/504or gRPCUNKNOWN: Stream removedat ~60s: Envoy enforces a hard 60-second total stream deadline onCONTENT_AUTHZ. NarrowAuthzPolicy.httpRulesto exclude long-running streams or gRPC channels.
Native MCP
AuthzPolicyHandshake403:If
AuthzPolicyuseshttpRules[].to.operations[].mcpwithaction: ALLOWand MCP clients fail oninitializeorping, setbaseProtocolMethodsOption: MATCH_BASE_PROTOCOL_METHODS(default isSKIP_BASE_PROTOCOL_METHODS).
Missing Spans in Cloud Trace (
TelemetryPolicyPreview):Verify
cloudtrace.googleapis.comis enabled,gcloud beta network-services telemetry-policies describe $POLICY_NAME --location=$LOCATION --project=$PROJECT_IDtargets the gateway with non-zerosamplingRate, androles/cloudtrace.agentis granted on the project to all three gateway service agents (service-${PROJECT_NUMBER}@compute-system.iam.gserviceaccount.com,service-${PROJECT_NUMBER}@gcp-sa-networksecurity.iam.gserviceaccount.com,service-${PROJECT_NUMBER}@gcp-sa-agentgateway.iam.gserviceaccount.com) plus the calling agent's workload SA (for parent spans).
Quick reference: the checks in order
When triaging a 403 or connection failure, walk these in order:
Confirm the error in the agent log (
403vs. SSL Handshake Timeout vs. Connection Reset vs. Crash).Find the exact hostname in the gateway log (if
403).Check IAP audit log: decision, principal, policy version (
iapPolicyVersion="v2"vs."V1"),iamEnforcementMode, and watch forunregisteredResource.3b. If no IAP audit entry, pull gateway proxy load-balancer log.
3c. If SSL Handshake Timeout or Connection Reset, run the PSC Subnet Exhaustion Check (
subnets describe,/28→/26).3d. If timeouts or silent connection drops to public internet under VPC-SC, verify Agent Connectivity Template (
vpcEgress: ALL_TRAFFICvs.PRIVATE_RANGES_ONLY) and Consumer Cloud NAT routing.
Confirm exact hostname permutation is registered in Agent Registry (
googleapisconsolidated service + custom entries).Check IAM / UAP Policies on the target:
IAM v1: Check
roles/iap.egressor(--resource-type=agent-registry).UAP (Policy V2): Check CRM
PolicyBinding(search-target-policy-bindings) andAccessPolicyacross Project, Folder, and Org; checkconstraints/iam.managed.disableAccessPolicyBinding(~30–60s propagation).
Check
AuthzExtension(iapPolicyVersion: "V2"vs."V1"),AuthzPolicytargets (omitloadBalancingScheme), and multi-registry constraints (max 2: 1global+ 1 same-region or same-jurisdiction multi-regional).Confirm least-privilege Agent Identity roles (no
expressUser/aiplatform.user; useagentInvokerfor A2A). 7b. Check PAB policies. 7c. Check Cloud Run egress auth (SA impersonation or--iap --functional-type=mcp-server).If behavior is flaky, test with a 1:1
principal://binding.If cross-project runtime binding (Project A → Gateway in Project B), verify deployer and service agent viewer permissions on Project B, regional colocation, CAA opt-out (
GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES: False), and server-generated resource UUID in IAP bindings.If routing egress through a transparent downstream Secure Web Proxy (SWP), verify
NEXT_HOP_ROUTING_MODE, PBR priority 200 on PSC-I subnet to--next-hop-ilb-ip, Cloud NATENDPOINT_TYPE_SWG, andGatewaySecurityPolicyCEL allowlist.If routing egress through an explicit corporate proxy (
HTTPS_PROXY=https://...:443returning404), verifygcloud betaL4AuthzPolicy(networkRulesmatchingsnis),NO_PROXY, container Private CA trust, and L7 bypass trade-offs.If private DNS returns
NXDOMAINor Shared VPC setup fails, verifydnsPeeringConfigtrailing dots, the 2-hop transitive DNS peering limit (authoritative zone at Hop 2), root"."forwarding-only rule, and dual-principal Host Project IAM.If Private CA
TrustConfigbreaks*.googleapis.comor edits fail to apply, setadditionalRoots: PUBLICLY_TRUSTED_ROOTSon a new ACT and rebind theAgentGateway.If requests fail at 60s (
Stream removed), return no SGP verdict or error on streaming, block MCPinitialize, or drop Cloud Trace spans, verify Model ArmorhttpRulesscoping & ingress/egress SAs, SGP non-streaming invocation +.contains()CEL filter & fullmetadatamap, MCPMATCH_BASE_PROTOCOL_METHODS, andTelemetryPolicyroles/cloudtrace.agentgrants.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an MCP server
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Publisher
- Google (Official)
- Source
- google/skills · skills/cloud/agent-platform-troubleshooting · commit 2194d3b
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Google.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download agent-platform-troubleshooting.zip