{"record":{"id":"98f42f583d14ce65","repo":"vitessio/vitess","slug":"method-not-allowed","errorCode":null,"errorMessage":"Method not allowed","messagePattern":"Method not allowed","errorType":"http","errorClass":null,"httpStatus":405,"severity":"warning","filePath":"go/vt/vttablet/tabletserver/debugenv.go","lineNumber":80,"sourceCode":"\treturn append(vars, envValue{\n\t\tName:  name,\n\t\tValue: fmt.Sprintf(\"%v\", f()),\n\t})\n}\n\nfunc debugEnvHandler(tsv *TabletServer, w http.ResponseWriter, r *http.Request) {\n\tif err := acl.CheckAccessHTTP(r, acl.ADMIN); err != nil {\n\t\tacl.SendError(w, err)\n\t\treturn\n\t}\n\n\tswitch r.Method {\n\tcase http.MethodPost:\n\t\thandlePost(tsv, w, r)\n\tcase http.MethodGet:\n\t\thandleGet(tsv, w, r)\n\tdefault:\n\t\thttp.Error(w, \"Method not allowed\", http.StatusMethodNotAllowed)\n\t}\n}\n\nfunc handlePost(tsv *TabletServer, w http.ResponseWriter, r *http.Request) {\n\tvarname := r.FormValue(\"varname\")\n\tvalue := r.FormValue(\"value\")\n\n\tvar msg string\n\tif varname == \"\" || value == \"\" {\n\t\thttp.Error(w, \"Missing varname or value\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tsetIntVal := func(f func(int)) error {\n\t\tival, err := strconv.Atoi(value)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"invalid int value for %v: %v\", varname, err)\n\t\t}","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletserver/debugenv.go#L62-L98","documentation":"The tabletserver /debugenv endpoint only accepts POST (set a variable) and GET (read variables); any other HTTP method gets a 405 'Method not allowed'. This is method-based routing in debugEnvHandler's switch on r.Method.","triggerScenarios":"Sending PUT, DELETE, HEAD, etc. to /debugenv on a vttablet's debug port.","commonSituations":"REST clients or proxies assuming full CRUD on debug endpoints; misconfigured health checkers using HEAD/DELETE; copy-pasted client code hitting the wrong verb.","solutions":["Use POST to set a variable (varname/value form fields) or GET to list them","Fix the client/proxy to send GET or POST only","If a middleware rewrites methods, whitelist /debugenv from such rewrites"],"exampleFix":"// before\ncurl -X PUT 'http://tablet:15100/debugenv?varname=x&value=1'\n// after\ncurl -X POST 'http://tablet:15100/debugenv' -d 'varname=x&value=1'","handlingStrategy":"validation","validationCode":"if method != http.MethodGet && method != http.MethodPost {\n    return fmt.Errorf(\"/debugenv only supports GET and POST, got %s\", method)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use GET (read) or POST (set) against /debugenv","Disable method-rewriting middleware for vttablet debug endpoints","Configure health checkers to use GET"],"tags":["http-api","vttablet","method-not-allowed"],"backgroundTag":"http-405-method-not-allowed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}