{"record":{"id":"6c9bc1e73742733f","repo":"caddyserver/caddy","slug":"unable-to-parse-url-pattern-w","errorCode":null,"errorMessage":"unable to parse URL pattern: %w","messagePattern":"unable to parse URL pattern: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/urlpatternmatcher.go","lineNumber":67,"sourceCode":"\t}\n}\n\n// Provision compiles the URL pattern.\nfunc (m *MatchURLPattern) Provision(_ caddy.Context) error {\n\tinput := m.Pattern\n\n\t// A relative pattern with no base matches any origin: prefix wildcard\n\t// protocol, host and port so only the path, search and hash are\n\t// constrained. The port wildcard is needed because a request Host may\n\t// carry an explicit port. Host-scoped matching stays opt-in via an\n\t// absolute pattern or base_url.\n\tif m.BaseURL == \"\" && !strings.Contains(input, \"://\") {\n\t\tinput = \"*://*:*\" + input\n\t}\n\n\tp, err := urlpattern.New(input, m.BaseURL, &urlpattern.Options{IgnoreCase: m.IgnoreCase})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to parse URL pattern: %w\", err)\n\t}\n\n\tm.compiledPattern = p\n\n\treturn nil\n}\n\n// Match returns true if the request matches the URL pattern.\nfunc (m *MatchURLPattern) Match(r *http.Request) bool {\n\tok, _ := m.MatchWithError(r)\n\n\treturn ok\n}\n\n// MatchWithError returns true if the request matches the URL pattern. The\n// request's origin (scheme://host) is the base against which the path is\n// resolved, so an absolute pattern or base_url can match on scheme and host.\n//","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/urlpatternmatcher.go#L49-L85","documentation":"Thrown when MatchURLPattern.Provision compiles the configured pattern via urlpattern.New(pattern, baseURL, opts) and the WICG URL Pattern parser rejects it. This is a config-validation error: the pattern string (and optional base_url) must be parseable URLPattern syntax (e.g. `/books/:id`, `https://example.com/books/*`). The wrapped error from the urlpattern library explains the syntax problem.","triggerScenarios":"A matcher block `@url_pattern pattern /books/{` or expression `url_pattern('/:id')` where the pattern has unmatched/invalid group syntax, a malformed base_url (e.g. `example.com` without scheme when the pattern needs one), a wildcard `*` placed where a full component is required, or invalid port/name characters. Fails at provision/validate time, before any request is matched.","commonSituations":"Confusing URLPattern syntax with regex or with nginx location syntax; forgetting that a relative pattern is auto-prefixed with `*://*:*` so the pattern must start with `/`; supplying a base_url with a path when the pattern is absolute; using `*` in the middle of a hostname component.","solutions":["Read the wrapped urlpattern error — it pinpoints the offending segment of the pattern","Make relative patterns path-absolute: start with `/` (e.g. `/books/:id`, `/search?q=*`)","Use `:name` for named segments and `*` only as a full-component wildcard (`/files/*`), not inside a component","If pattern is absolute (`scheme://host/...`), drop base_url, or set base_url to a full origin like `https://example.com`","Test the pair quickly: urlpattern.New accepts the same string as JavaScript's URLPattern, so try it in a browser console first"],"exampleFix":"# before\n@url_pattern {\n    pattern \"books/:id\"\n    base_url \"example.com\"\n}\n\n# after\n@url_pattern {\n    pattern \"/books/:id\"\n    base_url \"https://example.com\"\n}","handlingStrategy":"validation","validationCode":"// Validate patterns before deploying config (URLPattern mirrors JS URLPattern):\nfunc validPattern(pattern, base string) error {\n    in := pattern\n    if base == \"\" && !strings.Contains(in, \"://\") {\n        in = \"*://*:*\" + in // mirror Caddy's relative-pattern expansion\n    }\n    _, err := urlpattern.New(in, base, nil)\n    return err\n}","typeGuard":null,"tryCatchPattern":"// urlpattern.New returns (nil, err) rather than panicking; always check both:\np, err := urlpattern.New(pattern, baseURL, nil)\nif err != nil {\n    return fmt.Errorf(\"pattern %q rejected: %w\", pattern, err)\n}\nuse(p)","preventionTips":["Start relative patterns with `/` and use `:name` or full-component `*` only","Keep a small test that compiles every url_pattern in your config at CI time","Try the pattern in a browser console (new URLPattern) for fast feedback"],"tags":["matcher","urlpattern","caddyfile","validation","caddyhttp"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}