spring-projects/spring-boot · error · DockerEngineException

Docker API call to '{}' failed with status code {}

Error message

Docker API call to '{}' failed with status code {}

What it means

HttpClientTransport.execute saw an HTTP status in [400, 500] inclusive from the Docker daemon and threw DockerEngineException. The message is built by DockerEngineException.buildMessage: 'Docker API call to <host><uri> failed with status code <code>' plus optional reason phrase, response message, and structured Errors from the body. For status 500 the Errors deserialization is skipped (only Message is parsed). This is the umbrella exception for any Docker API request that the daemon rejected.

Source

Thrown at buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpClientTransport.java:170

	private Response execute(HttpUriRequestBase request, @Nullable String registryAuth) {
		if (StringUtils.hasText(registryAuth)) {
			request.setHeader(REGISTRY_AUTH_HEADER, registryAuth);
		}
		return execute(request);
	}

	private Response execute(HttpUriRequest request) {
		try {
			beforeExecute(request);
			ClassicHttpResponse response = this.client.executeOpen(this.host, request, null);
			int statusCode = response.getCode();
			if (statusCode >= 400 && statusCode <= 500) {
				byte[] content = readContent(response);
				response.close();
				Errors errors = (statusCode != 500) ? deserializeErrors(content) : null;
				Message message = deserializeMessage(content);
				throw new DockerEngineException(this.host.toHostString(), request.getUri(), statusCode,
						response.getReasonPhrase(), errors, message, content);
			}
			return new HttpClientResponse(response);
		}
		catch (IOException | URISyntaxException ex) {
			throw new DockerConnectionException(this.host.toHostString(), ex);
		}
	}

	protected void beforeExecute(HttpRequest request) {
	}

	private byte @Nullable [] readContent(ClassicHttpResponse response) throws IOException {
		HttpEntity entity = response.getEntity();
		if (entity == null) {
			return null;
		}
		try (InputStream stream = entity.getContent()) {

View on GitHub (pinned to 270dfe353f)

Solutions

  1. Read the structured detail from the exception: getStatusCode(), getReasonPhrase(), getErrors(), getResponseMessage() — the daemon's explanation is there.
  2. For 404, verify image and builder names and that the daemon can reach the registry (`docker pull <image>`).
  3. For 401/403, configure registry auth (`docker login`) so the buildpack can read config.json credentials.
  4. For 500, inspect `docker daemon` logs / `journalctl -u docker` for the server-side error.
Defensive patterns

Strategy: try-catch

Validate before calling

// Best-effort pre-checks: validate image references exist via `docker manifest inspect`
Process p = new ProcessBuilder("docker", "manifest", "inspect", imageRef)
        .redirectErrorStream(true).start();
if (p.waitFor() != 0) {
    throw new IllegalArgumentException("Image not found or inaccessible: " + imageRef);
}

Try / catch

try {
    transport.post(uri, auth);
} catch (DockerEngineException ex) {
    switch (ex.getStatusCode()) {
        case 401, 403 -> { /* configure registry auth: docker login */ }
        case 404      -> { /* verify image/builder reference */ }
        case 500      -> { /* inspect daemon logs; getResponseMessage()/getErrors() */ }
        default       -> { /* surface getErrors()/getResponseMessage() */ }
    }
    throw ex;
}

Prevention

When it happens

Trigger: Any of get/post/put/delete/head routes through execute (line 160); client.executeOpen returns a ClassicHttpResponse whose getCode() is >= 400 and <= 500. Examples: 404 pulling a builder/base image that does not exist; 401 pushing to a registry without credentials; 400 malformed reference/builder name; 500 daemon-side build failure.

Common situations: Referencing a builder image (docker.io/paketobuildpacks/builder:base) or run image that does not exist or is not accessible; pushing to a registry while unauthenticated; builder image incompatible with the daemon version; daemon disk full; reference/tag typo.

Related errors


AI-assisted analysis of spring-projects/spring-boot@270dfe353f (2026-08-11). Data as JSON: /api/errors/c21984b7c0b4761d. Report an issue: GitHub.