{"record":{"id":"98a34cf891dbb90f","repo":"theonedev/onedev","slug":"invalid-uploaded-content-hash-not-equals-to-objec","errorCode":null,"errorMessage":"Invalid uploaded content: hash not equals to object id","messagePattern":"Invalid uploaded content: hash not equals to object id","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/git/GitLfsFilter.java","lineNumber":300,"sourceCode":"\t\t\t\t\t\t\t\t\t\t\tsha256(), httpRequest.getInputStream())) {\n\t\t\t\t\t\t\t\t\t\tIOUtils.copy(is, output, BUFFER_SIZE);\n\t\t\t\t\t\t\t\t\t\thash.set(Hex.encodeHexString(is.hash().asBytes()));\n\t\t\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\t\t\toutput.close();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\ttry (Response lfsResponse = builder.post(Entity.entity(os, APPLICATION_OCTET_STREAM))) {\n\t\t\t\t\t\t\t\t\tKubernetesHelper.checkStatus(lfsResponse);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\tclient.close();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif (!objectId.equals(hash.get())) {\n\t\t\t\t\t\t\tlfsObject.delete();\n\t\t\t\t\t\t\tthrow new RuntimeException(\"Invalid uploaded content: hash not equals to object id\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\t\t\t\t\t\t\t\t\t\n\t\t} else if (httpRequest.getContentType() != null \n\t\t\t\t\t&& httpRequest.getContentType().startsWith(CONTENT_TYPE)\n\t\t\t\t|| httpRequest.getHeader(\"Accept\") != null \n\t\t\t\t\t&& httpRequest.getHeader(\"Accept\").startsWith(CONTENT_TYPE)) {\n\t\t\tString projectPath = getProjectPath(pathInfo);\n\t\t\tif (clusterAccess) {\n\t\t\t\tProjectFacade project = projectService.findFacadeByPath(projectPath);\n\t\t\t\tif (project == null) {\n\t\t\t\t\tsendBatchError(httpResponse, SC_NOT_FOUND, \"Project not found: \" + projectPath);\n\t\t\t\t} else {\n\t\t\t\t\thttpResponse.setContentType(CONTENT_TYPE);\n\t\t\t\t\tif (pathInfo.endsWith(\"/batch\")) \n\t\t\t\t\t\tprocessBatch(httpRequest, httpResponse, project, () -> true, () -> true, clusterService.getCredential());\n\t\t\t\t\telse ","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/git/GitLfsFilter.java#L282-L318","documentation":"While handling an LFS object upload, GitLfsFilter computes a hash (e.g. SHA-256) of the streamed body and compares it with the object id the client declared in the LFS API. On mismatch it deletes the stored lfsObject to avoid corrupt data and throws a RuntimeException. This protects the LFS store from incomplete or corrupted uploads.","triggerScenarios":"POST upload to the LFS object endpoint where the digest of received bytes != the oid announced in the LFS batch response; truncated uploads (network drop, proxy buffering limits), client-side file modified between batch negotiation and upload, or wrong oid in the batch request.","commonSituations":"Unstable network or request body size limits truncating the upload; reverse proxy closing the connection early; a retried upload reusing stale object content; non-LFS-aware proxy altering the body (compression); client LFS version bugs.","solutions":["Retry: git lfs push --all or git push to re-upload; the corrupt temp object was deleted server-side","Check for proxy/load-balancer request-body size limits or buffering that truncate uploads and raise them","Run git lfs fsck on the client to verify local object integrity, and git lfs fetch --all to repair","Update git-lfs client to a recent version to rule out hashing/upload bugs"],"exampleFix":"// before: plain push failing on big file\ngit push\n\n// after: verify then retry upload with tracing\ngit lfs fsck\nGIT_TRACE=1 GIT_TRANSFER_TRACE=1 git lfs push --all origin","handlingStrategy":"retry","validationCode":"// Client-side: verify file hash matches the oid declared in the batch request before upload\nconst hash = crypto.createHash('sha256').update(fileBuffer).digest('hex');\nif (hash !== lfsOid) throw new Error('Local object corrupted; run git lfs fsck');","typeGuard":null,"tryCatchPattern":"try {\n  await uploadLfsObject(object);\n} catch (e) {\n  if (e.message.includes('hash not equals to object id')) {\n    await gitLfsFsckAndRetry();\n  }\n}","preventionTips":["Run git lfs fsck before/after large transfers","Ensure proxies don't truncate or transform upload bodies","Retry failed LFS uploads rather than reusing partially uploaded state"],"tags":["git-lfs","upload","checksum-mismatch","onedev"],"backgroundTag":"checksum-mismatch","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}