JuliusBrussee/caveman · error

bedrock request path

Error message

bedrock request path %q is not allowed

What it means

ResolveUpstreamURL recognizes exactly two Bedrock route shapes: /bedrock/model/... (Runtime) and /bedrock/anthropic/... (Mantle). endpointKindForPath returns "" for anything else and the default case rejects it, keeping the proxy fail-closed on unknown routes rather than forwarding arbitrary paths to AWS.

Solutions

  1. Ensure the path starts with /bedrock/model/<modelId>/<action> for Runtime or /bedrock/anthropic/v1/messages for Mantle
  2. If the client sends raw AWS paths (/model/...), configure it to prefix them with /bedrock or fix the mount/base-path in caveman.yaml
  3. Check that no reverse proxy or rewrite rule in front of caveman stripped the /bedrock prefix
  4. Use a provider adapter matching the actual API if this is not Bedrock traffic (e.g. anthropic, openai)

Example fix

// before
POST /model/anthropic.claude-3-5-sonnet/invoke  // missing /bedrock prefix
// after
POST /bedrock/model/anthropic.claude-3-5-sonnet/invoke
Defensive patterns

Strategy: validation

Validate before calling

if !strings.HasPrefix(path, "/bedrock/model/") && !strings.HasPrefix(path, "/bedrock/anthropic/") {
	// only these two route shapes reach the Bedrock adapter
}

Prevention

When it happens

Trigger: Any request path not starting with /bedrock/model/ or /bedrock/anthropic/ sent to the Bedrock adapter, e.g. /bedrock/, /bedrock/foundation-models, /bedrock/model (no trailing slash + resource), or a client accidentally configured with provider=bedrock for a non-Bedrock path.

Common situations: A generic AWS SDK client pointed at the proxy issuing management-plane calls (ListFoundationModels, etc.) which the proxy does not route; misconfigured base path stripping so the /model/ segment is lost; clients using the raw AWS API path format (/model/{modelId}/invoke) without the required /bedrock prefix.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

		}
		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:
		return nil, fmt.Errorf("bedrock request path %q is not allowed", req.URL.Path)
	}
	base.RawQuery = req.URL.RawQuery

	if env.IsProduction() {
		if err := providers.ValidateUpstreamEndpoint(ctx, base, ssrf.ManagedConfig()); err != nil {
			return nil, err
		}
		hostKind, _, ok := bedrockHostKind(base.Hostname())
		if !ok || hostKind != kind {
			return nil, fmt.Errorf("bedrock endpoint host %q does not match endpoint kind %q", base.Hostname(), kind)
		}
	}
	return base, nil
}

func endpointKindForPath(path string) string {
	switch {
	case strings.HasPrefix(path, "/bedrock/model/"):

View on GitHub (pinned to 3ee70a1026)