{"record":{"id":"8da4a51a3e5e06d6","repo":"theonedev/onedev","slug":"tag-body-exceeds-maximum-size","errorCode":null,"errorMessage":"Tag body exceeds maximum size: ","messagePattern":"Tag body exceeds maximum size: ","errorType":"http","errorClass":"ClientException","httpStatus":406,"severity":"error","filePath":"server-plugin/server-plugin-pack-npm/src/main/java/io/onedev/server/plugin/pack/npm/NpmPackHandler.java","lineNumber":195,"sourceCode":"\t\t\t\t\t\t\t\t\t} catch (IOException e) {\n\t\t\t\t\t\t\t\t\t\tthrow new RuntimeException(e);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow new ClientException(SC_METHOD_NOT_ALLOWED);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsessionService.run(() -> {\n\t\t\t\t\t\t\t\tcheckProject(projectId, true);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tvar tag = decodePath(pathSegments.get(2));\n\t\t\t\t\t\t\tLockUtils.run(getLockName(projectId, packageName), () -> {\n\t\t\t\t\t\t\t\tif (isPut) {\n\t\t\t\t\t\t\t\t\tvar baos = new ByteArrayOutputStream();\n\t\t\t\t\t\t\t\t\ttry (var is = request.getInputStream()) {\n\t\t\t\t\t\t\t\t\t\tvar copied = copyWithMaxSize(is, baos, MAX_TAG_BODY_LEN);\n\t\t\t\t\t\t\t\t\t\tif (copied == -1)\n\t\t\t\t\t\t\t\t\t\t\tthrow new ClientException(SC_NOT_ACCEPTABLE, \"Tag body exceeds maximum size: \" + MAX_TAG_BODY_LEN);\n\t\t\t\t\t\t\t\t\t} catch (IOException e) {\n\t\t\t\t\t\t\t\t\t\tthrow new RuntimeException(e);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tvar version = StringUtils.strip(baos.toString(UTF_8), \"\\\"\");\n\t\t\t\t\t\t\t\t\ttransactionService.run(() -> {\n\t\t\t\t\t\t\t\t\t\tvar project = projectService.load(projectId);\n\t\t\t\t\t\t\t\t\t\tvar pack = packService.findByNameAndVersion(project, TYPE, packageName, version);\n\t\t\t\t\t\t\t\t\t\tif (pack != null) {\n\t\t\t\t\t\t\t\t\t\t\tvar packData = (NpmData) pack.getData();\n\t\t\t\t\t\t\t\t\t\t\tpackData.getDistTags().add(tag);\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tthrow new ClientException(SC_NOT_FOUND);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tresponse.setStatus(SC_OK);\n\t\t\t\t\t\t\t\t} else if (isDelete) {\n\t\t\t\t\t\t\t\t\ttransactionService.run(() -> {\n\t\t\t\t\t\t\t\t\t\tvar project = projectService.load(projectId);","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-pack-npm/src/main/java/io/onedev/server/plugin/pack/npm/NpmPackHandler.java#L177-L213","documentation":"When publishing/updating npm dist-tags via PUT, the handler buffers the request body up to MAX_TAG_BODY_LEN using copyWithMaxSize. If the body exceeds that limit (copy returns -1), it rejects the request with HTTP 406 Not Acceptable 'Tag body exceeds maximum size: <limit>'.","triggerScenarios":"PUT to the /-/package/<name>/dist-tags route with a body larger than MAX_TAG_BODY_LEN — the body should be a short quoted version string, so this happens when the client sends a large payload instead.","commonSituations":"Misconfigured clients that send full package metadata to the dist-tag endpoint; pipelined/multiplexed uploads posting the wrong body to the tag route; custom scripts posting JSON documents as a tag.","solutions":["Ensure the PUT dist-tag body is only the version string (e.g. \"1.2.3\")","Check client code/CI scripts for accidentally posting metadata or tarballs to the dist-tags endpoint","If a legitimate larger body is needed, raise MAX_TAG_BODY_LEN in NpmPackHandler or use the npm publish flow instead"],"exampleFix":"// before\nawait fetch(`${registry}/-/package/${name}/dist-tags/latest`, {method:'PUT', body: JSON.stringify(fullMetadata)})\n// after\nawait fetch(`${registry}/-/package/${name}/dist-tags/latest`, {method:'PUT', body: '\"1.2.3\"'})","handlingStrategy":"validation","validationCode":"const body = '\"1.2.3\"';\nif (body.length > 128) throw new Error('dist-tag body must be a short quoted version string');","typeGuard":null,"tryCatchPattern":"try { await putDistTag(url, body) } catch (e) { if (e.response?.status === 406 && /Tag body exceeds maximum size/i.test(e.message ?? '')) { console.error('Dist-tag PUT body too large — send only the version string'); } else throw e }","preventionTips":["PUT only the version string to dist-tag endpoints","Never send package metadata or tarballs to dist-tag routes","Review CI scripts that construct dist-tag calls manually"],"tags":["http-406","npm","payload-size","dist-tags"],"backgroundTag":"file-size-limit-exceeded","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"}