JuliusBrussee/caveman · error
bedrock base url invalid: %w
Error message
bedrock base url invalid: %w
What it means
The Bedrock adapter parses its base URL (route.BaseURL if set, else the adapter default) before routing, and a malformed value — one that url.Parse rejects — produces this wrapped parse error. Unlike the base adapter, Bedrock needs a parsed URL early because region and endpoint-kind resolution derive from it (runtime vs mantle paths).
Source
Thrown at proxy/providers/bedrock/routing.go:154
)
// ResolveUpstreamURL validates the endpoint kind, region, action, and model
// resource, then resolves one of two explicit Bedrock surfaces:
//
// - Runtime: /bedrock/model/... -> bedrock-runtime.../model/...
// - Mantle: /bedrock/anthropic/v1/messages -> bedrock-mantle.../anthropic/...
//
// Mantle stays deployment-opt-in because its IAM service, model coverage,
// quotas, features, stream wire, and AWS invocation-logging support differ from
// Runtime. Both surfaces remain provider=bedrock in telemetry.
func (a Adapter) ResolveUpstreamURL(ctx context.Context, req *http.Request, route providers.RouteContext) (*url.URL, error) {
baseURL := a.BaseURL
if route.BaseURL != "" {
baseURL = route.BaseURL
}
base, err := url.Parse(baseURL)
if err != nil {
return nil, fmt.Errorf("bedrock base url invalid: %w", err)
}
region, err := resolveRegion(req, base)
if err != nil {
return nil, err
}
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)View on GitHub (pinned to 27d5a3981a)
Solutions
- Fix the base_url value to a well-formed absolute URL, e.g. https://bedrock-runtime.us-east-1.amazonaws.com.
- Validate at config load: if _, err := url.Parse(v); err != nil { return fmt.Errorf("bad base_url: %w", err) }.
- Inspect the raw config/env for hidden characters (cat -A) after templating.
Example fix
# before base_url: "https://bedrock-runtime.us-east-1.amazonaws.com:%zz" # after base_url: "https://bedrock-runtime.us-east-1.amazonaws.com"
Defensive patterns
Strategy: validation
Validate before calling
base := strings.TrimSpace(route.BaseURL)
if base == "" {
base = strings.TrimSpace(adapterBaseURL)
}
if _, err := url.Parse(base); err != nil {
return fmt.Errorf("bedrock base_url %q is not parseable: %w", base, err)
} Type guard
func isParseableURL(raw string) bool {
_, err := url.Parse(strings.TrimSpace(raw))
return err == nil
} Try / catch
if _, err := adapter.ResolveUpstreamURL(ctx, req, route); err != nil {
if strings.Contains(err.Error(), "base url invalid") {
http.Error(w, "bedrock base_url is malformed; fix provider config", http.StatusBadGateway)
return
}
http.Error(w, err.Error(), http.StatusBadRequest)
} Prevention
- url.Parse-check every configured base URL at config load.
- Use cat -A to spot hidden characters after templating.
- Prefer full https URLs with region hostnames for bedrock.
When it happens
Trigger: Configuring base_url with invalid URL syntax: unmatched percent-encoding ('%zz'), a control character, malformed port ('https://host:port'), or stray whitespace past trimming.
Common situations: Hand-edited YAML with a truncated URL; env interpolation inserting an empty or partial value; a pasted URL containing a literal newline; template engines emitting bad percent-escapes.
Related errors
- bedrock configured endpoint kind %q does not allow request k
- provider %q upstream URL must be absolute
- cachebench: no providers
- cachebench: provider population exceeds 1024
- cachebench: invalid observation read limits
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/c8659c4142f5a2a4.
Report an issue: GitHub.