{"record":{"id":"761c2a1857a82309","repo":"JuliusBrussee/caveman","slug":"vertex-endpoint-host-q-is-not-an-aiplatform-host","errorCode":null,"errorMessage":"vertex endpoint host %q is not an aiplatform host","messagePattern":"vertex endpoint host %q is not an aiplatform host","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/providers/vertex/routing.go","lineNumber":66,"sourceCode":"\tif route.BaseURL != \"\" {\n\t\tbaseURL = route.BaseURL\n\t}\n\tbase, err := url.Parse(baseURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"vertex base url invalid: %w\", err)\n\t}\n\tbase.Path = strings.TrimRight(base.Path, \"/\") + strings.TrimPrefix(req.URL.Path, \"/vertex\")\n\tbase.RawQuery = req.URL.RawQuery\n\n\t// SSRF/host validation on the resolved endpoint. Active in managed (prod)\n\t// mode; local/self-hosted (stub) endpoints are permitted so the dry-run and\n\t// examples can target the provider-stub.\n\tif env.IsProduction() {\n\t\tif err := ssrf.ValidateURL(ctx, base.String(), ssrf.ManagedConfig()); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif host := base.Hostname(); !isVertexHost(host) {\n\t\t\treturn nil, fmt.Errorf(\"vertex endpoint host %q is not an aiplatform host\", host)\n\t\t}\n\t}\n\treturn base, nil\n}\n\nfunc methodAllowed(publisher, method string) bool {\n\tswitch publisher {\n\tcase \"google\":\n\t\treturn method == \"generateContent\" || method == \"streamGenerateContent\"\n\tcase \"anthropic\":\n\t\treturn method == \"rawPredict\" || method == \"streamRawPredict\"\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// InspectRequest fills in request metadata. Vertex carries the model id in the\n// request path (.../models/{model}:{method}) rather than the body, so the model","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/766dce6b1394ebb56a3090748d5a0240a5aefb36/proxy/providers/vertex/routing.go#L48-L84","documentation":"After SSRF validation, the resolved endpoint host is not a recognized Google aiplatform host. The gate ensures the constructed upstream URL (base + stripped /vertex path) actually points at the aiplatform service and not some other host that survived URL assembly — a defense against misconfigured base URLs or path tricks.","triggerScenarios":"Thrown at proxy/providers/vertex/routing.go:66 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Point the Vertex base URL at a valid aiplatform endpoint (e.g. https://aiplatform.googleapis.com)","In non-managed/stub mode, use the provider-stub endpoint designed for the dry-run instead of an arbitrary host"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"766dce6b1394ebb56a3090748d5a0240a5aefb36","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}