theonedev/onedev · error · ClientException

UNSUPPORTED

UNSUPPORTED

Error message

Unsupported digest: ${digestString}

What it means

The container registry servlet only supports sha256 digests. When a client references a manifest or blob with a digest algorithm other than sha256 (e.g. sha512), parseDigest throws this 406 ClientException with code UNSUPPORTED. This is a deliberate limitation of the registry implementation, not a transient failure.

Source

Thrown at server-plugin/server-plugin-pack-container/src/main/java/io/onedev/server/plugin/pack/container/ContainerServlet.java:508

	}
	
	private String getBlobUrl(String projectPath, String repository, String digest) {
		return "/v2/" + projectPath + "/" + repository + "/blobs/" + digest;
	}

	private String getManifestUrl(String projectPath, String repository, String reference) {
		return "/v2/" + projectPath + "/" + repository + "/manifests/" + reference;
	}
	
	private boolean isTag(String reference) {
		return !reference.contains(":");
	}
	
	private Digest parseDigest(String digestString) {
		if (digestString.startsWith("sha256:")) {
			return new Digest(SHA256, digestString.substring("sha256:".length()));
		} else {
			throw new ClientException(SC_NOT_ACCEPTABLE, ErrorCode.UNSUPPORTED, 
					"Unsupported digest: " + digestString);
		}
	}
	
	private Project checkProject(String projectPath, boolean needsToPush) {
		var project = projectService.findByPath(projectPath);
		if (project == null) 
			throw new NotFoundException(ErrorCode.NAME_UNKNOWN, "Unknown project: " + projectPath);
		else if (!project.isPackManagement())
			throw new ClientException(SC_NOT_ACCEPTABLE, ErrorCode.DENIED, "Package management not enabled for project: " + projectPath);
		else if (needsToPush && !SecurityUtils.canWritePack(project))
			throw new UnauthorizedException("No package write permission for project: " + project.getPath());
		else if (!needsToPush && !SecurityUtils.canReadPack(project))
			throw new UnauthorizedException("No package read permission for project: " + project.getPath());
		else
			return project;
	}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Change the request to use a sha256: digest (the default for docker/OCI tooling).
  2. If a client is pushing/pulling sha512 digests, re-tag and re-push the image so digests are computed with sha256.
  3. Check for a proxy/mirror in front of the registry rewriting digests to another algorithm and fix its configuration.

Example fix

// before
docker pull registry.example.com/project@sha512:abcd...
// after
docker pull registry.example.com/project@sha256:abcd...
Defensive patterns

Strategy: validation

Validate before calling

if (!digestString.startsWith("sha256:")) throw new IllegalArgumentException("only sha256 digests supported: " + digestString);

Type guard

function isSha256Digest(d: string): boolean { return /^sha256:[a-f0-9]{64}$/.test(d); }

Prevention

When it happens

Trigger: A Docker/OCI client sends a request whose path or header contains a digest with an algorithm prefix other than 'sha256:' — e.g. GET /v2/<name>/manifests/sha512:<hex> or a manifest list referencing sha512 blob digests.

Common situations: Using a container client configured (or a registry proxy negotiating) sha512 digest algorithm; copying artifacts between registries where the source stored non-sha256 digests; hand-crafted REST calls to the registry API using another algorithm.

Related errors


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