{"record":{"id":"01e0fc66fa7f26c0","repo":"juicedata/juicefs","slug":"400-bad-request","errorCode":null,"errorMessage":"400 Bad Request","messagePattern":"400 Bad Request","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/fs/http.go","lineNumber":329,"sourceCode":"\t//\n\t// If a request was sent with an XML body which included an empty namespace\n\t// prefix declaration (xmlns:ns1=\"\"), then the server must reject that with\n\t// a \"400 Bad Request\" response, as it is invalid according to the XML\n\t// Namespace specification.\"\n\t//\n\t// On the other hand, the Go standard library's encoding/xml package\n\t// accepts an empty xmlns namespace, as per the discussion at\n\t// https://github.com/golang/go/issues/8068\n\t//\n\t// Empty namespaces seem disallowed in the second (2006) edition of the XML\n\t// standard, but allowed in a later edition. The grammar differs between\n\t// http://www.w3.org/TR/2006/REC-xml-names-20060816/#ns-decl and\n\t// http://www.w3.org/TR/REC-xml-names/#dt-prefix\n\t//\n\t// Thus, we assume that the propfind_invalid2 test is obsolete, and\n\t// hard-code the 400 Bad Request response that the test expects.\n\tif r.Header.Get(\"X-Litmus\") == \"props: 3 (propfind_invalid2)\" {\n\t\thttp.Error(w, \"400 Bad Request\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tif !h.EnableProppatch && r.Method == \"PROPPATCH\" {\n\t\thttp.Error(w, \"The PROPPATCH method is not currently enabled,please add the --enable-proppatch parameter and run it again\", http.StatusNotImplemented)\n\t\treturn\n\t}\n\n\th.Handler.ServeHTTP(w, r)\n}\n\nfunc newWebdavHandler(fs *FileSystem, config WebdavConfig) http.Handler {\n\tctx := meta.NewContext(uint32(os.Getpid()), uint32(utils.GetCurrentUID()), []uint32{uint32(utils.GetCurrentGID())})\n\thfs := &webdavFS{ctx, fs, uint16(utils.GetUmask()), config}\n\tsrv := &webdav.Handler{\n\t\tFileSystem: hfs,\n\t\tLockSystem: webdav.NewMemLS(),\n\t\tLogger: func(r *http.Request, err error) {","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/fs/http.go#L311-L347","documentation":"The WebDAV handler in pkg/fs/http.go returns a literal '400 Bad Request' body when it detects the litmus conformance test case 'props: 3 (propfind_invalid2)', which sends a malformed PROPFIND XML body. The RFC4918 suite historically expected servers to reject invalid namespace declarations; the handler hard-codes this response for that specific test header.","triggerScenarios":"Sending a PROPFIND request with header 'X-Litmus: props: 3 (propfind_invalid2)' to the WebDAV endpoint; also any client that happens to set this header. Ordinary malformed PROPFIND bodies are handled by golang.org/x/net/webdav, not this branch.","commonSituations":"Running the litmus WebDAV compliance test suite against a JuiceFS WebDAV mount; proxy or test harness replaying recorded litmus traffic.","solutions":["If you are running litmus, this is the expected pass response — no action needed","If a real client sends this header unintentionally, remove the X-Litmus header from the request","For genuinely malformed PROPFIND XML (without the header), fix the client's XML namespace declarations"],"exampleFix":"// before\nreq.Header.Set(\"X-Litmus\", \"props: 3 (propfind_invalid2)\")\n// after\nreq.Header.Del(\"X-Litmus\") // send a well-formed PROPFIND body instead","handlingStrategy":"validation","validationCode":"// Don't send litmus test headers in production clients\nif strings.HasPrefix(r.Header.Get(\"X-Litmus\"), \"props:\") { strip header before sending }","typeGuard":"func isLitmusProbe(h http.Header) bool { return h.Get(\"X-Litmus\") != \"\" }","tryCatchPattern":null,"preventionTips":["Never set X-Litmus headers outside conformance test runs","Send well-formed PROPFIND XML with correct namespace declarations","Use litmus only against dedicated test volumes"],"tags":["http","webdav","bad-request"],"backgroundTag":"http-error-response","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}