{"record":{"id":"6df258e5de07cf73","repo":"caddyserver/caddy","slug":"s","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"http","errorClass":"caddyhttp.Error","httpStatus":null,"severity":"info","filePath":"modules/caddyhttp/fileserver/matcher.go","lineNumber":539,"sourceCode":"\t\t\treturn false, nil\n\t\t}\n\t\tsetPlaceholders(recent, recentInfo.IsDir())\n\t\treturn true, nil\n\t}\n\n\treturn false, nil\n}\n\n// parseErrorCode checks if the input is a status\n// code number, prefixed by \"=\", and returns an\n// error if so.\nfunc parseErrorCode(input string) error {\n\tif len(input) > 1 && input[0] == '=' {\n\t\tcode, err := strconv.Atoi(input[1:])\n\t\tif err != nil || code < 100 || code > 999 {\n\t\t\treturn nil\n\t\t}\n\t\treturn caddyhttp.Error(code, fmt.Errorf(\"%s\", input[1:]))\n\t}\n\treturn nil\n}\n\n// strictFileExists returns true if file exists\n// and matches the convention of the given file\n// path. If the path ends in a forward slash,\n// the file must also be a directory; if it does\n// NOT end in a forward slash, the file must NOT\n// be a directory.\nfunc (m MatchFile) strictFileExists(fileSystem fs.FS, file string) (os.FileInfo, bool) {\n\tinfo, err := fs.Stat(fileSystem, file)\n\tif err != nil {\n\t\t// in reality, this can be any error\n\t\t// such as permission or even obscure\n\t\t// ones like \"is not a directory\" (when\n\t\t// trying to stat a file within a file);\n\t\t// in those cases we can't be sure if","sourceCodeStart":521,"sourceCodeEnd":557,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/fileserver/matcher.go#L521-L557","documentation":"Raised by MatchFile when a try_files pattern of the form '=NNN' (e.g. '=404') is evaluated and no earlier candidate matched. It is not a bug: parseErrorCode converts the '=NNN' token into a caddyhttp.Error carrying that status code, which Caddy then renders as the HTTP response. It only triggers when the numeric suffix parses (Atoi succeeds) and is in the range 100-999.","triggerScenarios":"A request reaches a route with `try_files {path} {path}/ =404` (or any '=NNN' token) where every preceding file candidate fails to stat, so the loop at matcher.go:444 reaches the '=NNN' pattern and returns its error.","commonSituations":"Standard SPA/static-site fallback config ('try_files {path} /index.html =404'); the error appears in logs when a client requests a missing asset and the intended behavior is to serve a 404. Also seen when someone writes '=404' expecting a redirect or rewrite instead of a status.","solutions":["Treat it as expected behavior: the '=NNN' token exists precisely to terminate file matching with that status; no code fix is needed.","If clients should get a page instead of a bare status, put a real fallback file (e.g. /index.html) before the '=404' token in try_files.","If you did not intend a status fallback, remove the '=NNN' entry from try_files.","If the log noise is unwanted, lower the access/matcher log level or route these requests with a matcher that excludes missing assets."],"exampleFix":"# before\ntry_files {path} {path}/ =404\n# after (serve SPA fallback before falling back to 404)\ntry_files {path} /index.html =404","handlingStrategy":"validation","validationCode":"// In config/tooling: detect '=NNN' try_files tokens and confirm the status is intended\nfor _, pattern := range tryFiles {\n    if strings.HasPrefix(pattern, \"=\") {\n        code, err := strconv.Atoi(pattern[1:])\n        if err != nil || code < 100 || code > 999 {\n            return fmt.Errorf(\"invalid status fallback %q\", pattern)\n        }\n        // intentional: request will terminate with this status when reached\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Document in your config that '=NNN' in try_files is a terminal status fallback, not a file.","Place real fallback files (e.g. /index.html) before '=404' so users get content, not bare statuses.","Add monitoring that separates expected 404s from '=404' fallbacks if the noise matters."],"tags":["caddy","fileserver","try-files","matcher","status-code"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}