JuliusBrussee/caveman · error
production requires CAVE_PUBLIC_URL to be an HTTPS origin…
Error message
production requires CAVE_PUBLIC_URL to be an HTTPS origin without credentials, path, query, or fragment
What it means
validateProductionPublicURL requires CAVE_PUBLIC_URL to be exactly an HTTPS origin: scheme https, non-empty hostname, no userinfo, no query, no fragment, and path empty or '/'. Any deviation raises this fixed-message error so the public data plane always advertises a clean canonical origin.
Solutions
- Set CAVE_PUBLIC_URL to a bare HTTPS origin, e.g. https://api.example.com (no path/query/fragment/credentials).
- Ensure TLS terminates in front of the service so https is the correct public scheme.
- If a path prefix is needed, configure it elsewhere — this variable must stay an origin only.
- If the URL fails to parse at all, fix malformed syntax (spaces, missing scheme).
Example fix
// before export CAVE_PUBLIC_URL="http://api.example.com/api?env=prod" // error: production requires CAVE_PUBLIC_URL to be an HTTPS origin without credentials, path, query, or fragment // after export CAVE_PUBLIC_URL="https://api.example.com"
Defensive patterns
Strategy: validation
Validate before calling
func checkPublicURL() error {
u, err := url.Parse(strings.TrimSpace(os.Getenv("CAVE_PUBLIC_URL")))
if err != nil || u.Scheme != "https" || u.Hostname() == "" || u.User != nil ||
u.RawQuery != "" || u.Fragment != "" || (u.Path != "" && u.Path != "/") {
return errors.New("CAVE_PUBLIC_URL must be a bare HTTPS origin, e.g. https://api.example.com")
}
return nil
} Try / catch
if err := env.RefuseProductionDefaults(); err != nil {
if strings.Contains(err.Error(), "CAVE_PUBLIC_URL") {
log.Fatalf("bad public URL: %v", err)
}
return err
} Prevention
- Store the public origin as scheme + host only, never a full path with query/fragment.
- Ensure TLS is provisioned before setting CAVE_PUBLIC_URL to an https origin.
- Add a URL lint step to deploy pipelines that mirrors this rule.
When it happens
Trigger: RefuseProductionDefaults or RefuseGatewayProductionDefaults runs while CAVE_PUBLIC_URL is http://, missing, has a path like /api, includes credentials (user:pass@), or carries ?query or #fragment.
Common situations: Setting the URL to a localhost http address in a prod deploy; including a trailing API path; pasting a full URL with query params from a browser; leaving the variable empty so it parses to nothing.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- postgres: production DATABASE_URL must be a Postgres URL
- invalid CAVEMAN_LISTEN
- invalid listener
- : every source must be HTTPS
- must be an absolute http(s) URL
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/9e6e15f50f73b42d.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/env/env.go:117
v := strings.TrimSpace(os.Getenv(name))
if v == "" || v == "generated" || strings.Contains(strings.ToLower(v), "changeme") {
return fmt.Errorf("production refuses default or empty %s", name)
}
if len(v) < 32 {
return fmt.Errorf("production requires %s to contain at least 32 characters", name)
}
if distinctBytes([]byte(v)) < 8 {
return fmt.Errorf("production refuses low-diversity %s", name)
}
}
return nil
}
func validateProductionPublicURL() error {
publicURL := strings.TrimSpace(os.Getenv("CAVE_PUBLIC_URL"))
u, err := url.Parse(publicURL)
if err != nil || u.Scheme != "https" || u.Hostname() == "" || u.User != nil || u.RawQuery != "" || u.Fragment != "" || (u.Path != "" && u.Path != "/") {
return fmt.Errorf("production requires CAVE_PUBLIC_URL to be an HTTPS origin without credentials, path, query, or fragment")
}
return nil
}
func distinctBytes(value []byte) int {
seen := map[byte]struct{}{}
for _, b := range value {
seen[b] = struct{}{}
}
return len(seen)
}
View on GitHub (pinned to 3ee70a1026)