JuliusBrussee/caveman · error

vertex publisher %q is not on the allowlist

Error message

vertex publisher %q is not on the allowlist

What it means

The publisher segment of the Vertex path is not in defaultPublishers ("google", "anthropic"), so publisherAllowed rejected it. This is a deliberate cost-containment gate: requests to partner publishers the gateway does not price are refused before any upstream call.

Source

Thrown at proxy/providers/vertex/routing.go:41

// Operators override it with CAVE_VERTEX_MODEL_ALLOWLIST.
var defaultModelPrefixes = []string{"gemini-", "claude-"}

// ResolveUpstreamURL validates the Vertex request shape (publisher + model on
// the allowlist), enforces SSRF/host constraints against the aiplatform
// endpoint, and resolves the upstream URL. The /vertex prefix is stripped so the
// upstream path is the native aiplatform path
// (/v1/projects/{p}/locations/{l}/publishers/{pub}/models/{model}:{method}). The
// query string (e.g. ?alt=sse) is preserved unchanged — byte-safe passthrough.
func (a Adapter) ResolveUpstreamURL(ctx context.Context, req *http.Request, route providers.RouteContext) (*url.URL, error) {
	publisher, model, method := parsePredictPath(req.URL.Path)
	if publisher == "" || model == "" || method == "" {
		return nil, fmt.Errorf("vertex request path %q does not name a publisher, model, and method", req.URL.Path)
	}
	if !methodAllowed(publisher, method) {
		return nil, fmt.Errorf("vertex method %q is not allowed for publisher %q", method, publisher)
	}
	if !publisherAllowed(publisher) {
		return nil, fmt.Errorf("vertex publisher %q is not on the allowlist", publisher)
	}
	if !modelAllowed(model) {
		return nil, fmt.Errorf("vertex model %q is not on the allowlist", model)
	}

	baseURL := a.BaseURL
	if route.BaseURL != "" {
		baseURL = route.BaseURL
	}
	base, err := url.Parse(baseURL)
	if err != nil {
		return nil, fmt.Errorf("vertex base url invalid: %w", err)
	}
	base.Path = strings.TrimRight(base.Path, "/") + strings.TrimPrefix(req.URL.Path, "/vertex")
	base.RawQuery = req.URL.RawQuery

	// SSRF/host validation on the resolved endpoint. Active in managed (prod)
	// mode; local/self-hosted (stub) endpoints are permitted so the dry-run and

View on GitHub (pinned to 766dce6b13)

Solutions

  1. Use publisher google or anthropic in the path
  2. Extend the publisher set (defaultPublishers) only after the model catalog covers the partner's pricing
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at proxy/providers/vertex/routing.go:41 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of JuliusBrussee/caveman@766dce6b13 (2026-08-18). Data as JSON: /api/errors/c5ebff4673f3dada. Report an issue: GitHub.