{"record":{"id":"4e1010866c38cd13","repo":"caddyserver/caddy","slug":"method-not-allowed","errorCode":null,"errorMessage":"method not allowed","messagePattern":"method not allowed","errorType":"http","errorClass":"APIError","httpStatus":405,"severity":"error","filePath":"admin.go","lineNumber":1131,"sourceCode":"\tif !ok {\n\t\treturn APIError{\n\t\t\tHTTPStatus: http.StatusNotFound,\n\t\t\tErr:        fmt.Errorf(\"unknown object ID '%s'\", id),\n\t\t}\n\t}\n\n\t// piece the full URL path back together\n\tparts = append([]string{expanded}, parts[3:]...)\n\tr.URL.Path = path.Join(parts...)\n\n\treturn errInternalRedir\n}\n\nfunc handleStop(w http.ResponseWriter, r *http.Request) error {\n\tif r.Method != http.MethodPost {\n\t\treturn APIError{\n\t\t\tHTTPStatus: http.StatusMethodNotAllowed,\n\t\t\tErr:        fmt.Errorf(\"method not allowed\"),\n\t\t}\n\t}\n\n\texitProcess(context.Background(), Log().Named(\"admin.api\"))\n\treturn nil\n}\n\nfunc parseCanonicalArrayIndex(idx string) (int, error) {\n\tif idx == \"\" {\n\t\treturn 0, fmt.Errorf(\"empty index\")\n\t}\n\ti, err := strconv.Atoi(idx)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif strconv.Itoa(i) != idx {\n\t\treturn 0, fmt.Errorf(\"non-canonical array index\")\n\t}","sourceCodeStart":1113,"sourceCodeEnd":1149,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/admin.go#L1113-L1149","documentation":"Returned by the admin API's handleStop handler when the request method is not POST. Stopping Caddy via the /stop endpoint is a state-changing action, so only POST is accepted; anything else gets HTTP 405 'method not allowed'.","triggerScenarios":"GET http://localhost:2019/stop, or PUT/DELETE on /stop. Any non-POST request to the stop endpoint.","commonSituations":"Browsing to /stop in a web browser (which issues GET); REST clients defaulting to GET; scripts that confuse /stop with the read-only /config endpoints which do allow GET.","solutions":["Send POST: curl -X POST http://localhost:2019/stop","If you only meant to inspect state, use GET /config/ instead of /stop"],"exampleFix":"# before\ncurl http://localhost:2019/stop\n# after\ncurl -X POST http://localhost:2019/stop","handlingStrategy":"validation","validationCode":"curl -X POST http://localhost:2019/stop  # always POST; never GET","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Mutating admin endpoints (/stop, /load) accept POST only","Keep browsers/probes away from /stop; a browser GET will only get 405, but the intent is unclear"],"tags":["caddy","admin-api","http","method-not-allowed","lifecycle"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}