amir20/dozzle · warning
err.Error()
Error message
err.Error()
What it means
downloadLogs returns a 400 with the regex parse error when the `filter` query parameter cannot be compiled as a regular expression. support_web.ParseRegex wraps regexp.Compile, so any syntactically invalid Go RE2 pattern (unbalanced parens, bad escape sequences, invalid character classes) is rejected before any container lookup happens.
Solutions
- Validate the filter pattern with regexp.Compile before building the download URL.
- URL-encode the filter parameter (encodeURIComponent / url.QueryEscape) so metacharacters survive transport.
- Fall back to no filter if the pattern fails to compile.
Example fix
// before
const url = `/api/hosts/${host}/containers/${id}/download?filter=${userInput}`
// after
const re = new RegExp(userInput) // or regexp.Compile server-side
if (!isValidGoRegex(userInput)) throw new Error('invalid filter regex')
const url = `/api/hosts/${host}/containers/${id}/download?filter=${encodeURIComponent(userInput)}` Defensive patterns
Strategy: validation
Validate before calling
function isValidGoRegex(p) {
try { new RegExp(p); return p.indexOf('\\') === -1 || !/\\[QEHAGKZR]/.test(p); } catch { return false; }
}
if (!isValidGoRegex(filter)) throw new Error(`invalid filter regex: ${filter}`) Prevention
- URL-encode the filter query parameter every time.
- Stick to RE2-compatible syntax; avoid PCRE-only constructs.
- Test filter patterns against regexp.Compile before shipping them in URLs.
When it happens
Trigger: GET /api/hosts/{host}/containers/{id}/download with a query like ?filter=([a-] or ?filter=\Q, i.e. any filter string that fails regexp.Compile.
Common situations: Users hand-crafting filter URLs; UI escaping bugs where user search input is placed raw into the query string; patterns copied from PCRE-flavored tools that use RE2-unsupported or invalid syntax.
Related errors
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/3eed7425e6424db5.
Report an issue: GitHub.
Appendix: source
Thrown at internal/web/download.go:66
if r.URL.Query().Has("stdout") {
stdTypes |= container.STDOUT
}
if r.URL.Query().Has("stderr") {
stdTypes |= container.STDERR
}
if stdTypes == 0 {
http.Error(w, "stdout or stderr is required", http.StatusBadRequest)
return
}
// Parse filter regex if provided
var regex *regexp.Regexp
var err error
if r.URL.Query().Has("filter") {
regex, err = support_web.ParseRegex(r.URL.Query().Get("filter"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
// Inverse mode excludes lines matching the regex instead of keeping them.
inverse := r.URL.Query().Get("inverse") == "true"
// Parse level filters if provided
levels := make(map[string]struct{})
if r.URL.Query().Has("levels") {
for _, level := range r.URL.Query()["levels"] {
levels[level] = struct{}{}
}
}
// Validate all containers before starting to write response
type containerInfo struct {
hostId stringView on GitHub (pinned to d9463cbe21)