JuliusBrussee/caveman · error

bedrock model is not on the allowlist

Error message

bedrock model %q is not on the allowlist

What it means

ResolveUpstreamURL in the Bedrock adapter validates the model id from a /bedrock/model/{modelId}/{action} request path against the allowlist (built-in prefixes like anthropic.claude-, amazon.nova-, or the CAVE_BEDROCK_MODEL_ALLOWLIST override). The proxy deliberately blocks any model outside this closed list so unverified model ids (and their pricing/availability) cannot be routed to Bedrock. If the model id fails both the identifier validity check and prefix/allowlist matching, the request is rejected before any upstream call.

Solutions

  1. Verify the exact model id in the request path and fix typos (ids are prefix-matched, so 'anthropic.claude-3-5-sonnet-20241022-v2:0' matches 'anthropic.claude-')
  2. Add the model to CAVE_BEDROCK_MODEL_ALLOWLIST (comma-separated, prefix matches allowed) and restart the proxy
  3. If using an inference profile, keep the scope prefix (us./eu./global.) — it is stripped before prefix matching
  4. If the model is new on AWS, upgrade the proxy to a version whose defaultModelPrefixes covers it
  5. If passing a full model ARN, ensure it is well-formed (arn:aws:bedrock:<region>:<account>:foundation-model/...) — a malformed ARN falls back to identifier/prefix checks

Example fix

// before
CAVE_BEDROCK_MODEL_ALLOWLIST=anthropic.claude-3-5-sonnet
// request: /bedrock/model/anthropic.claude-opus-4/invoke -> rejected
// after
CAVE_BEDROCK_MODEL_ALLOWLIST=anthropic.claude-3-5-sonnet,anthropic.claude-
Defensive patterns

Strategy: validation

Validate before calling

func runtimeModelAllowed(modelID string) bool {
	for _, p := range []string{"anthropic.claude-", "amazon.nova-", "amazon.titan-", "meta.llama2", "meta.llama3", "meta.llama4", "mistral.", "cohere.", "ai21."} {
		if strings.HasPrefix(modelID, p) {
			return true
		}
	}
	return false
}
// call before issuing: if !runtimeModelAllowed(modelID) { fix config }

Prevention

When it happens

Trigger: A POST to /bedrock/model/<modelId>/invoke (or converse, count-tokens, etc.) where modelId does not match a default prefix and is not in CAVE_BEDROCK_MODEL_ALLOWLIST; e.g. a typo'd model id ('anthropic.claude35-sonnet'), a model from another vendor prefix not covered (e.g. 'deepseek.r1'), or an operator-set custom allowlist that omits the model.

Common situations: Typo in the model id in client config; using a newly released AWS model before the proxy's built-in prefix list was updated; an operator narrowing CAVE_BEDROCK_MODEL_ALLOWLIST and forgetting to include a model clients still use; expecting ARN-models to pass but supplying a malformed ARN (valid ARNs bypass the prefix list only when the allowlist env is unset).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/679e1347e3b253a4. Report an issue: GitHub.

Appendix: source

Thrown at proxy/providers/bedrock/routing.go:178

	kind := endpointKindForPath(req.URL.Path)
	if configuredKind := strings.ToLower(strings.TrimSpace(route.EndpointKind)); configuredKind != "" && configuredKind != kind {
		return nil, fmt.Errorf("bedrock configured endpoint kind %q does not allow request kind %q", configuredKind, kind)
	}
	switch kind {
	case endpointRuntime:
		if !RegionAllowed(region) {
			return nil, fmt.Errorf("bedrock region %q is not on the allowlist", region)
		}
		modelID, action := parseModelPath(req.URL.Path)
		if modelID == "" || action == "" {
			return nil, fmt.Errorf("bedrock request path %q does not name a model and action", req.URL.Path)
		}
		if !actionAllowed(action) {
			return nil, fmt.Errorf("bedrock action %q is not allowed", action)
		}
		if !modelAllowed(modelID) {
			return nil, fmt.Errorf("bedrock model %q is not on the allowlist", modelID)
		}
		base.Path = strings.TrimRight(base.Path, "/") + strings.TrimPrefix(req.URL.Path, "/bedrock")
	case endpointMantle:
		if !env.Bool("CAVE_BEDROCK_MANTLE_ENABLED", false) {
			return nil, fmt.Errorf("bedrock Mantle endpoint is not enabled")
		}
		if !MantleRegionAllowed(region) {
			return nil, fmt.Errorf("bedrock Mantle region %q is not on the allowlist", region)
		}
		if !mantleActionAllowed(req.URL.Path) {
			return nil, fmt.Errorf("bedrock Mantle path %q is not allowed", req.URL.Path)
		}
		base, err = resolveMantleBase(base, region)
		if err != nil {
			return nil, err
		}
		base.Path = strings.TrimRight(base.Path, "/") + strings.TrimPrefix(req.URL.Path, "/bedrock")
	default:

View on GitHub (pinned to 3ee70a1026)