{"record":{"id":"aeec5cc254cf328b","repo":"gohugoio/hugo","slug":"failed-to-compile-headers-glob-q-w","errorCode":null,"errorMessage":"failed to compile Headers glob %q: %w","messagePattern":"failed to compile Headers glob %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/commonConfig.go","lineNumber":256,"sourceCode":"}\n\nfunc (r redirect) matchHeader(header http.Header) bool {\n\tfor k, v := range r.headers {\n\t\tif !v.Match(header.Get(k)) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (s *Server) CompileConfig(logger loggers.Logger) error {\n\tif s.compiledHeaders != nil {\n\t\treturn nil\n\t}\n\tfor _, h := range s.Headers {\n\t\tg, err := glob.Compile(h.For)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to compile Headers glob %q: %w\", h.For, err)\n\t\t}\n\t\ts.compiledHeaders = append(s.compiledHeaders, g)\n\t}\n\tfor _, r := range s.Redirects {\n\t\tif r.From == \"\" && r.FromRe == \"\" {\n\t\t\treturn fmt.Errorf(\"redirects must have either From or FromRe set\")\n\t\t}\n\t\trd := redirect{\n\t\t\theaders: make(map[string]glob.Glob),\n\t\t}\n\t\tif r.From != \"\" {\n\t\t\tg, err := glob.Compile(r.From)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to compile Redirect glob %q: %w\", r.From, err)\n\t\t\t}\n\t\t\trd.from = g\n\t\t}\n\t\tif r.FromRe != \"\" {","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/config/commonConfig.go#L238-L274","documentation":"Emitted by Server.CompileConfig while compiling each entry in server.Headers. Each header's `for` field is compiled with gobwas/glob (not regexp). If the glob pattern is malformed (unbalanced braces/brackets, invalid char-class), the compile fails and is wrapped with the offending `for` value.","triggerScenarios":"A `[[server.headers]]` block whose `for` glob is invalid, e.g. unbalanced `{` or a malformed character class.","commonSituations":"Writing a dev-server header rule and using regex syntax instead of glob; copy-paste leaving a dangling brace.","solutions":["Use glob syntax for `for` (supports *, ?, {a,b}, character classes).","Balance any braces and brackets.","Strip the rule to a simple `/*` and re-add complexity."],"exampleFix":"# before\n[[server.headers]]\nfor = \"/*.{js,css\"\n\n# after\n[[server.headers]]\nfor = \"/*.{js,css}\"","handlingStrategy":"validation","validationCode":"python3 - <<'PY'\n# Approximate glob sanity: balance braces/brackets\nimport tomllib\ncfg=tomllib.loads(open('hugo.toml').read())\nfor h in cfg.get('server',{}).get('headers',[]):\n    f=h['for']\n    assert f.count('{')==f.count('}'), f\"unbalanced braces in {f!r}\"\n    assert f.count('[')==f.count(']'), f\"unbalanced brackets in {f!r}\"\nprint(\"headers glob ok\")\nPY","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use gobwas/glob syntax (not regexp) for server.headers `for`.","Balance braces and brackets.","Prefer simple `/*.{ext1,ext2}` patterns."],"tags":["config","server","glob","headers"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}