400 name: must match ^[a-z0-9-]{3,40}$ | Invalid gateway name (uppercase, underscore, dash at edge, too short/long). | Use 3–40 lowercase letters / digits / dashes, no leading/trailing dash. |
400 privateNetwork is required when networkMode=PRIVATE | PRIVATE mode without vpcId / subnetId. | Supply both. Discover via vserver.sh. |
| 400 invalid CIDR / non-IPv4 / public range | Route entry isn't a private IPv4 CIDR. | Use RFC 1918 ranges only; IPv6 and public ranges are rejected. |
| 409 Conflict on create | A gateway with the same name already exists for this user. | Choose a different name. |
| 412 Precondition Failed | Stale If-Match — someone (including a previous async transition) bumped resourceVersion. | GET the gateway, rebase your patch, retry. Expected on retry loops. |
| 422 quota / no eligible flavor / target cap | User over their gateway quota, no flavor matches the selected networkMode + zoneId, or targets.length > gateway.maxTargets. | Free a slot, pick a different flavor, or split into multiple gateways. |
State stuck on CREATING / UPDATING | Backend rollout still in progress, or hitting a transient infra issue. | Poll GET. If it transitions to ERROR / UPDATE_ERROR, inspect lastError (stage / code / message). |
lastError.stage = applyRoutes, state UPDATE_ERROR | Routes update failed during rollout. | Read the message verbatim; usually a CIDR overlap or VPC peering issue. Retry PUT /routes after fixing the input. |
iam.lastAuthFailureAt set, callers hitting 502 | Gateway service account got reset/disabled out-of-band. | POST /gateways/{name}/service-account/repair. Brief rollout follows. |
| 502 from upstream MCP call | Target endpoint unreachable, TLS error, or outbound auth misconfigured. | Verify target endpoint is reachable from gateway's network mode; check outboundAuth (header name, OAuth provider). For PRIVATE gateways, confirm the upstream IP is reachable via the configured routes. |
| Policy denies legitimate caller | Bound Policy Group has a deny rule matching the caller, or no allow matches (deny-by-default). | Review with /agentbase-policy. Remember deny wins inside a group and tools/list is always allowed regardless of policy. |
| 401 Unauthorized | Expired or invalid IAM token. | Re-obtain with bash .claude/skills/agentbase/scripts/get_token.sh --force. Confirm GREENNODE_CLIENT_ID / GREENNODE_CLIENT_SECRET. |
| 403 Forbidden | Service account lacks Gateway service permissions. | Check IAM roles at https://iam.console.vngcloud.vn. |
| 404 Not Found on routes endpoints | Gateway is PUBLIC (no routes resource exists) or the name is wrong. | Routes endpoints are PRIVATE-only. Verify networkMode via GET /gateways/{name}. |