theonedev/onedev · error · ExplicitException

Invalid blob size: %s

Error message

Invalid blob size: %s

What it means

DefaultPackBlobService.readBlob downloads the blob for a sha256 hash and validates that the number of bytes read matches the size recorded in the packBlob metadata row. A mismatch means stored metadata and actual stored/transferred content disagree, so the library throws ExplicitException to prevent returning corrupt data.

Source

Thrown at server-core/src/main/java/io/onedev/server/service/impl/DefaultPackBlobService.java:453

				dao.persist(packBlob);
				return new Pair<>(packBlob.getId(), true);
			} else if (checkPackBlobFile(projectId, sha256Hash, blobSize)) {
				return new Pair<>(packBlob.getId(), false);
			} else {
				return new Pair<>(packBlob.getId(), true);
			}
		});
	}

	@Override
	public byte[] readBlob(Long projectId, String sha256Hash) {
		var packBlob = findBySha256Hash(projectId, sha256Hash);
		if (packBlob != null) {
			var baos = new ByteArrayOutputStream();
			downloadBlob(projectId, sha256Hash, baos);
			var bytes = baos.toByteArray();
			if (bytes.length != packBlob.getSize())
				throw new ExplicitException("Invalid blob size: " + sha256Hash);
			return bytes;
		} else {
			throw new ExplicitException("Blob not found: " + sha256Hash);
		}
	}

	@Override
	public void downloadBlob(Long projectId, String sha256Hash, OutputStream os) {
		var activeServer = projectService.getActiveServer(projectId, true);
		if (activeServer.equals(clusterService.getLocalServerAddress())) {
			read(getFileLockName(projectId, sha256Hash), () -> {
				try (var is = new FileInputStream(getPackBlobFile(projectId, sha256Hash))) {
					copy(is, os, BUFFER_SIZE);
				}
				return null;
			});
		} else {
			Client client = ClientBuilder.newClient();

View on GitHub (pinned to d44925c47c)

Solutions

  1. Re-publish / re-upload the affected package blob so metadata and data are rewritten
  2. Delete the corrupt pack blob record and blob data, then republish the package
  3. Check storage health (disk space, S3 integrity) and server logs around the upload time
  4. Restore blob storage from a backup consistent with the database

Example fix

// before: blindly reading
byte[] data = packBlobService.readBlob(projectId, sha256Hash);
// after: fall back to re-download with size check
try {
    byte[] data = packBlobService.readBlob(projectId, sha256Hash);
} catch (ExplicitException e) {
    if (e.getMessage().startsWith("Invalid blob size")) {
        // republish blob or fetch from upstream registry
    }
    throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

var blob = packBlobService.findBySha256Hash(projectId, sha256Hash);
if (blob == null) throw new ExplicitException("Blob not published: " + sha256Hash);

Try / catch

try {
    return packBlobService.readBlob(projectId, sha256Hash);
} catch (ExplicitException e) {
    if (e.getMessage().startsWith("Invalid blob size")) {
        // mark blob corrupt and re-upload before retrying
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling PackBlobService.readBlob(projectId, sha256Hash) when the blob data on disk/object store is truncated, partially uploaded, or corrupted relative to the size recorded when the pack blob was published.

Common situations: Interrupted blob upload leaving a partial file; storage backend (NFS/S3) truncation or silent corruption; backup/restore mismatch between metadata DB and blob storage; concurrent modification of blob files.

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


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/3d58b62473f6661a. Report an issue: GitHub.