JuliusBrussee/caveman · error

bedrock requested region

Error message

bedrock requested region %q does not match endpoint region %q

What it means

resolveRegion keeps routing and AWS SigV4 signing on a single region: if the client explicitly requests a region via the x-cave-aws-region header while the configured base URL host already encodes a region (e.g. bedrock-runtime.eu-west-1.amazonaws.com), the two must agree. A contradictory pair is rejected rather than validating one region and dialing another, which would produce a signature scoped for the wrong region.

Solutions

  1. Make x-cave-aws-region match the region in the configured base URL host, or remove the header and let the host region win
  2. Update the route base_url to the region the clients request (e.g. bedrock-runtime.us-east-1.amazonaws.com)
  3. Audit both sides after a region migration — header and host must change together
  4. If no explicit region is needed, drop the header entirely; precedence is host region, then header, then CAVE_BEDROCK_REGION/AWS_REGION/AWS_DEFAULT_REGION

Example fix

// before
base_url: https://bedrock-runtime.eu-west-1.amazonaws.com
x-cave-aws-region: us-east-1  // mismatch -> rejected
// after
x-cave-aws-region: eu-west-1
Defensive patterns

Strategy: validation

Validate before calling

hostRegion := extractRegion(baseHost) // 2nd DNS label of bedrock-runtime.<region>.amazonaws.com
if hdr := req.Header.Get("x-cave-aws-region"); hdr != "" && hostRegion != "" && hdr != hostRegion {
	// fix header or base URL before sending
}

Prevention

When it happens

Trigger: Sending x-cave-aws-region: us-east-1 while the route's base URL host resolves to a different region (e.g. bedrock-runtime.eu-west-1.amazonaws.com, or a Mantle host bedrock-mantle.eu-west-1.api.aws) — in either direction of mismatch.

Common situations: Stale x-cave-aws-region header left from a previous configuration while the operator changed the base URL region; a multi-region deployment where clients pin regions that no longer match updated base URLs; copy-pasted route configs where the host was updated but client headers were not (or vice versa).

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

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

	}
	idx := strings.LastIndex(rest, "/")
	if idx <= 0 || idx == len(rest)-1 {
		return "", ""
	}
	return rest[:idx], rest[idx+1:]
}

// resolveRegion keeps routing, allowlisting, and signing on one region. A
// recognized endpoint host is authoritative; a contradictory client header is
// rejected rather than validating one region and dialing another.
func resolveRegion(req *http.Request, base *url.URL) (string, error) {
	requested := strings.TrimSpace(req.Header.Get("x-cave-aws-region"))
	hostRegion := ""
	if base != nil {
		hostRegion = regionFromHost(base.Hostname())
	}
	if requested != "" && hostRegion != "" && requested != hostRegion {
		return "", fmt.Errorf("bedrock requested region %q does not match endpoint region %q", requested, hostRegion)
	}
	if hostRegion != "" {
		return hostRegion, nil
	}
	if requested != "" {
		return requested, nil
	}
	if r := regionFromHost(req.Header.Get("x-cave-bedrock-host")); r != "" {
		return r, nil
	}
	return environmentRegion(), nil
}

// environmentRegion mirrors the precedence the proxy's own config uses
// (CAVE_BEDROCK_REGION, then the standard AWS variables) so a request whose
// upstream host does not name a region — a VPC endpoint, a PrivateLink host —
// is signed for the region the operator actually configured instead of
// silently falling back to us-east-1 and failing the signature.

View on GitHub (pinned to 3ee70a1026)