{"record":{"id":"7d989f34dcd5a1f0","repo":"theonedev/onedev","slug":"invalid-http-method-for-manifest-pull-method","errorCode":null,"errorMessage":"Invalid http method for manifest pull: ${method}","messagePattern":"Invalid http method for manifest pull: (.+?)","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server-plugin/server-plugin-pack-container/src/main/java/io/onedev/server/plugin/pack/container/ContainerServlet.java","lineNumber":430,"sourceCode":"\t\t\t\t\t\t\tpackBlobService.downloadBlob(manifestInfo.getLeft(), manifestInfo.getRight(), baos);\n\t\t\t\t\t\t\tbytes = baos.toByteArray();\n\t\t\t\t\t\t\tresponse.setContentType(new ContainerManifest(bytes).getMediaType());\n\t\t\t\t\t\t\tif (method.equals(\"GET\")) \n\t\t\t\t\t\t\t\tresponse.getOutputStream().write(bytes);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new NotFoundException(ErrorCode.MANIFEST_UNKNOWN);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"DELETE\":\n\t\t\t\t\t\tsessionService.run(() -> {\n\t\t\t\t\t\t\tvar project = checkProject(projectPath, true);\n\t\t\t\t\t\t\tif (isTag(reference))\n\t\t\t\t\t\t\t\tpackService.deleteByNameAndVersion(project, TYPE, repository, reference);\n\t\t\t\t\t\t\tresponse.setStatus(SC_ACCEPTED);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new BadRequestException(\"Invalid http method for manifest pull: \" + method);\n\t\t\t\t}\n\t\t\t} else if ((matcher = compile(\"(.+)/([^/]+)/tags/list\").matcher(pathInfo)).matches()) {\n\t\t\t\tvar projectPath = matcher.group(1);\n\t\t\t\tvar repository = matcher.group(2);\n\t\t\t\tsessionService.run(() -> {\n\t\t\t\t\tvar project = checkProject(projectPath, false);\n\n\t\t\t\t\tvar result = new HashMap<String, Object>();\n\t\t\t\t\tresult.put(\"name\", projectPath + \"/\" + repository);\n\t\t\t\t\tvar tags = new ArrayList<String>();\n\t\t\t\t\tresult.put(\"tags\", tags);\n\n\t\t\t\t\tint count = Integer.MAX_VALUE;\n\t\t\t\t\tvar countParam = request.getParameter(\"n\");\n\t\t\t\t\tif (countParam != null)\n\t\t\t\t\t\tcount = Integer.parseInt(countParam);\n\t\t\t\t\tif (count != 0) {\n\t\t\t\t\t\tvar lastTag = request.getParameter(\"last\");","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-pack-container/src/main/java/io/onedev/server/plugin/pack/container/ContainerServlet.java#L412-L448","documentation":"The manifest endpoint supports GET/HEAD (pull), PUT (push), and DELETE (remove by tag); any other method falls through to this BadRequestException. The message is phrased for the pull path but applies to any unsupported method on /v2/<name>/manifests/<reference>.","triggerScenarios":"Methods other than GET/HEAD/PUT/DELETE sent to /v2/<name>/manifests/<reference> — e.g. POST to the manifests URL, PATCH attempting partial manifest updates, or OPTIONS from preflight scanners.","commonSituations":"Clients using POST-based creation (some generic REST wrappers); tooling attempting PATCH-style manifest editing, which OCI does not allow; security probes hitting the manifests route.","solutions":["Pull with GET (or HEAD), push with PUT, delete with DELETE on /v2/<name>/manifests/<reference>.","Replace POST/PATCH usage with a full PUT of the complete manifest.","Note DELETE only works by tag; deleting by digest is not supported here — delete via tag or prune server-side.","Fix client URL/method mapping for the OCI distribution API."],"exampleFix":"// before\nPOST /v2/app/manifests/1.0  body=manifest.json\n// after\nPUT /v2/app/manifests/1.0  body=manifest.json","handlingStrategy":"validation","validationCode":"const MANIFEST_METHODS = ['GET','HEAD','PUT','DELETE'];\nif (!MANIFEST_METHODS.includes(method)) {\n  throw new Error(`/manifests/ accepts GET/HEAD/PUT/DELETE only, got ${method}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Full-manifest PUT instead of POST/PATCH-style updates.","Delete manifests by tag only.","Keep client method/URL mapping aligned with the OCI distribution API.","Ignore OPTIONS preflight noise from scanners; it is unsupported by design."],"tags":["oci-registry","http-method","manifest","bad-request"],"backgroundTag":"unsupported-operation","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}