theonedev/onedev · error · ClientException
Integrity check failed:
Error message
Integrity check failed:
What it means
npm publish attachments carry an 'integrity' field (format '<algorithm>-<base64 hash>'). The handler verifies each attachment's bytes by hashing with the declared algorithm (sha512 or sha1) and comparing to the decoded hash. A mismatch throws ClientException HTTP 400 'Integrity check failed: <fileName>'; unsupported algorithms are also rejected.
Source
Thrown at server-plugin/server-plugin-pack-npm/src/main/java/io/onedev/server/plugin/pack/npm/NpmPackHandler.java:438
if (entry.getValue().equals(version))
distTagsOfVersion.add(entry.getKey());
}
var distNode = versionMetadata.get("dist");
versionMetadata.remove("dist");
byte[] versionMetadataBytes = writeJson(versionMetadata);
if (distNode != null) {
var fileName = substringAfterLast(distNode.get("tarball").asText(), "-/");
var fileContent = attachments.get(fileName);
if (fileContent != null) {
var integrity = distNode.get("integrity").asText();
var algorithm = substringBefore(integrity, "-");
var hash = Base64.decodeBase64(substringAfter(integrity, "-"));
if (algorithm.equals("sha512")) {
if (!Arrays.equals(decodeHex(Digest.sha512Of(fileContent).getHash()), hash)) {
throw new ClientException(SC_BAD_REQUEST, "Integrity check failed: " + fileName);
}
} else if (algorithm.equals("sha1")) {
if (!Arrays.equals(decodeHex(Digest.sha1Of(fileContent).getHash()), hash)) {
throw new ClientException(SC_BAD_REQUEST, "Integrity check failed: " + fileName);
}
} else {
var errorMessage = String.format("Unexpected integrity algorithm (file: %s, algorithm: %s)",
fileName, algorithm);
throw new ClientException(SC_BAD_REQUEST, errorMessage);
}
var packBlobId = packBlobService.uploadBlob(projectId, fileContent, null);
var sha256Hash = packBlobService.load(packBlobId).getSha256Hash();
pack.setData(new NpmData(packageMetadataBytes, versionMetadataBytes, distTagsOfVersion, fileName, sha256Hash));
packService.createOrUpdate(pack, newArrayList(packBlobService.load(packBlobId)), true);
response.setStatus(SC_CREATED);
}
}
});View on GitHub (pinned to d44925c47c)
Solutions
- Re-run npm publish so integrity is recomputed from the actual attachment bytes
- Verify the integrity string is '<algorithm>-<base64(hash)>' matching the exact data sent (use only sha512 or sha1)
- Check for proxies/AV gateways modifying request bodies
- Compare the local file's sha512 against the metadata integrity value before publishing
Example fix
// before (hand-built metadata) "integrity": "sha256-..." // unsupported algorithm // after "integrity": "sha512-<base64 of sha512 digest>"
Defensive patterns
Strategy: validation
Validate before calling
const crypto = require('crypto');
for (const [name, att] of Object.entries(meta._attachments)) {
const bytes = Buffer.from(att.data, 'base64');
const [alg, b64] = att.integrity.split('-');
if (!['sha512','sha1'].includes(alg)) throw new Error(`Unsupported integrity algorithm: ${alg}`);
const digest = crypto.createHash(alg).update(bytes).digest('base64');
if (digest !== b64) throw new Error(`Integrity mismatch for ${name}`);
} Type guard
function hasValidIntegrity(att) {
const [alg, b64] = (att?.integrity ?? '').split('-');
return (alg === 'sha512' || alg === 'sha1') && typeof b64 === 'string' && b64.length > 0;
} Try / catch
try { await publish() } catch (e) { if (e.response?.status === 400 && /Integrity check failed/i.test(e.message ?? '')) { console.error('Attachment bytes do not match integrity hash — republish with standard npm client'); } else throw e } Prevention
- Use standard npm publish so integrity is computed correctly
- Only use sha512 or sha1 integrity values
- Avoid proxies that rewrite request bodies
- Verify hashes locally before scripted publishes
When it happens
Trigger: Publishing where an attachment's content differs from what its integrity hash was computed over — truncated or altered tarballs, wrong hash pasted into hand-built metadata, or an unsupported algorithm value.
Common situations: Corrupted uploads over flaky networks; scripts computing integrity over a different file version than embedded in 'data'; base64/hex encoding confusion when hand-crafting payloads; tampering or proxy rewriting of bodies.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- File length incorrect:
- Digest mismatch
- Invalid blob size: %s
- Checksum verification failed
- Invalid request path
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/796d46a01e548609.
Report an issue: GitHub.