quarkusio/quarkus · error · RuntimeException

Unable to create container image

Error message

Unable to create container image

What it means

JibProcessor.containerize() wraps the entire Jib build/push operation in a broad catch block and rethrows any Exception as RuntimeException("Unable to create container image", e). It is a generic failure boundary: the real cause (auth failure, network error, registry rejection, daemon error, bad config) is in the wrapped cause.

Source

Thrown at extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java:273

        Containerizer containerizer = createContainerizer(containerImageConfig, jibConfig, containerImage, pushRequested);
        for (String additionalTag : containerImage.getAdditionalTags()) {
            containerizer.withAdditionalTag(additionalTag);
        }

        // Jib uses the Google HTTP Client under the hood which attempts to record traces via OpenCensus which is wired
        // to delegate to OpenTelemetry.
        // This can lead to problems with the Quarkus OpenTelemetry extension which expects Vert.x to be running,
        // something that is not the case at build time, see https://github.com/quarkusio/quarkus/issues/22864.
        try (var resettableSystemProperties = ResettableSystemProperties
                .of(OPENTELEMETRY_CONTEXT_CONTEXT_STORAGE_PROVIDER_SYS_PROP, "default")) {
            JibContainer container = containerizeUnderLock(jibContainerBuilder, containerizer);
            log.infof("%s container image %s (%s)\n",
                    containerImageConfig.isPushExplicitlyEnabled() ? "Pushed" : "Created",
                    container.getTargetImage(),
                    container.getDigest());
            return container;
        } catch (Exception e) {
            throw new RuntimeException("Unable to create container image", e);
        }
    }

    private Containerizer createContainerizer(ContainerImageConfig containerImageConfig,
            ContainerImageJibConfig jibConfig, ContainerImageInfoBuildItem containerImageInfo,
            boolean pushRequested) {
        Containerizer containerizer;
        ImageReference imageReference = ImageReference.of(containerImageInfo.getRegistry().orElse(null),
                containerImageInfo.getRepository(), containerImageInfo.getTag());

        if (pushRequested || containerImageConfig.isPushExplicitlyEnabled()) {
            if (imageReference.getRegistry() == null) {
                log.info("No container image registry was set, so 'docker.io' will be used");
            }
            RegistryImage registryImage = toRegistryImage(imageReference, containerImageConfig.username(),
                    containerImageConfig.password());
            containerizer = Containerizer.to(registryImage);
        } else {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Read the full stack trace's cause (the wrapped exception) — this message itself is only a wrapper
  2. Run with -Dquarkus.jib.base-jvm-image or verify image names: quarkus.container-image.image, .registry, .group, .name
  3. Verify registry credentials: docker login to the target registry, or set quarkus.container-image.username/password
  4. Check network/proxy access to the registry and that the registry exists
  5. If pushing, confirm quarkus.container-image.push=true and the repository path is correct/created

Example fix

// before: opaque failure, no idea why
mvn package -Dquarkus.container-image.build=true
// after: isolate the cause and configure explicitly
mvn package -Dquarkus.container-image.build=true -X 2>&1 | grep -A20 'Caused by'
Defensive patterns

Strategy: try-catch

Validate before calling

// before invoking the image build
java.io.File dockerCfg = new java.io.File(System.getProperty("user.home"), ".docker/config.json");
if (push && !dockerCfg.exists()) throw new IllegalStateException("No docker credentials; run docker login first");
String image = config.registry() + "/" + config.group() + "/" + config.name() + ":" + config.tag();
// sanity-check image name format
if (!image.matches("[a-z0-9./:_-]+")) throw new IllegalStateException("Invalid image name: " + image);

Try / catch

try {
    buildContainerImage();
} catch (RuntimeException e) {
    // 'Unable to create container image' wraps the real cause
    Throwable cause = e.getCause();
    log.errorf(e, "Jib image build failed: %s", cause == null ? e : cause.getMessage());
    if (cause != null && cause.getMessage() != null && cause.getMessage().contains("Unauthorized")) {
        throw new IllegalStateException("Registry auth failed; run docker login", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Running a container-image build (mvn package -Dquarkus.container-image.build=true or quarkus:build target) where any step inside containerize() throws: Jib's build() fails, registry authentication fails, base image pull fails, layer extraction fails, or push to registry is rejected.

Common situations: Unauthenticated registry access (missing ~/.docker/config.json credentials), no network/DNS to registry, invalid base image name in quarkus.container-image.* config, registry rate limits, container-image.registry or username/password misconfiguration, JVM_OPTS/memory issues during layer processing.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/135ae2816fced56e. Report an issue: GitHub.