theonedev/onedev · error · ClientException
Method Not Allowed
Error message
Method Not Allowed
What it means
The Cargo pack registry handler routes requests under /api/v1/crates/... . Cargo's publish endpoint (/api/v1/crates/new) only accepts PUT (as cargo client uses) and download endpoints only accept GET; any other HTTP method on those paths results in a ClientException with status 405 Method Not Allowed.
Source
Thrown at server-plugin/server-plugin-pack-cargo/src/main/java/io/onedev/server/plugin/pack/cargo/CargoPackHandler.java:106
this.objectMapper = objectMapper;
}
@Override
public String getHandlerId() {
return HANDLER_ID;
}
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
Long projectId, Long buildId, List<String> pathSegments) {
var method = request.getMethod();
var isGet = method.equals("GET");
var isPut = method.equals("PUT");
var isDelete = method.equals("DELETE");
if (pathSegments.equals(newArrayList("api", "v1", "crates", "new"))) {
if (!isPut)
throw new ClientException(SC_METHOD_NOT_ALLOWED);
publish(request, response, projectId, buildId);
} else if (pathSegments.size() == 6
&& pathSegments.subList(0, 3).equals(newArrayList("api", "v1", "crates"))
&& pathSegments.get(5).equals("download")) {
if (!isGet)
throw new ClientException(SC_METHOD_NOT_ALLOWED);
download(response, projectId, decodePath(pathSegments.get(3)), decodePath(pathSegments.get(4)));
} else if (pathSegments.size() == 6
&& pathSegments.subList(0, 3).equals(newArrayList("api", "v1", "crates"))
&& pathSegments.get(5).equals("yank")) {
if (!isDelete)
throw new ClientException(SC_METHOD_NOT_ALLOWED);
setYanked(response, projectId, decodePath(pathSegments.get(3)), decodePath(pathSegments.get(4)), true);
} else if (pathSegments.size() == 6
&& pathSegments.subList(0, 3).equals(newArrayList("api", "v1", "crates"))
&& pathSegments.get(5).equals("unyank")) {
if (!isPut)
throw new ClientException(SC_METHOD_NOT_ALLOWED);View on GitHub (pinned to d44925c47c)
Solutions
- Use the cargo client itself: `cargo publish` issues PUT to /api/v1/crates/new; `cargo` download uses GET.
- If testing manually, send `curl -X PUT` for publish (with the cargo payload) and plain GET for download URLs.
- Check any reverse proxy/rewrite rules that may convert request methods.
Example fix
// before curl -X POST https://onedev.example.com/~builds/1/api/v1/crates/new ... // after curl -X PUT https://onedev.example.com/~builds/1/api/v1/crates/new ...
Defensive patterns
Strategy: validation
Validate before calling
const allowed = {"/api/v1/crates/new": ["PUT"], "/api/v1/crates/download": ["GET"]};
if (!allowed[pathKey]?.includes(method)) throw new Error("Wrong HTTP method for " + pathKey); Try / catch
try {
await publishPackage();
} catch (e) {
if (e.response && e.response.status === 405) {
console.error("Method not allowed: use PUT for publish, GET for download");
}
} Prevention
- Always use the cargo client (cargo publish / cargo fetch) rather than hand-rolled HTTP calls.
- Remember cargo spec: PUT /api/v1/crates/new, GET .../download.
- Check proxies/rewrites don't mutate the HTTP method.
When it happens
Trigger: Sending POST/GET to /api/v1/crates/new instead of PUT, or POST/PUT/DELETE to a /api/v1/crates/{crate}/{version}/download path instead of GET.
Common situations: Manually testing the registry with curl using the wrong verb; a proxy or tool rewriting PUT to POST; scripts using generic REST conventions (POST to publish) against the cargo-compatible API.
Related errors
- Invalid publish request body
- Package management not enabled for project '${projectPath}'
- No package read permission for project: ${projectPath}
- Method not allowed
- 405
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/cd93446396f31449.
Report an issue: GitHub.