How to Safely Remove Docker Image Tags Without Deleting the Image

Manage image tags is a common task when working with Docker. Occasionally, a tag might be applied incorrectly, perhaps due to a typographical error, or it may simply no longer be needed.

The challenge then becomes removing such a tag without inadvertently deleting the underlying image data, especially if that image is still in use or referenced by other tags.

This guide explores the mechanisms within Docker for tag removal, focusing on preserving the actual image layers. We will delve into how Docker handles images and tags, and outline practical solutions for effective tag management.

Understanding Docker Images and Tags

Before diving into removal methods, it’s helpful to clarify the relationship between Docker images and tags:

  • Image ID: A Docker image is fundamentally a set of read-only layers, uniquely identified by an Image ID (a SHA256 digest). This ID represents the actual image content.
  • Tag: A tag is a human-readable label or alias that points to an Image ID. It typically takes the form repository/image_name:version_label (e.g., my-app/service:1.2.0) or just image_name:version_label (e.g., ubuntu:latest).
  • Multiple Tags, One Image: A single Image ID can have multiple tags pointing to it. For instance, 0a1b2c3d4e5f (an Image ID) might be tagged as both my-app:latest and my-app:v1.0-stable.

The distinction is crucial: removing a tag means removing a pointer. Whether the underlying image data (identified by the Image ID) is also removed depends on whether other tags or references (like child images) still point to it.

Consider the following scenario where an image has two tags for the same Image ID, 0a1b2c3d4e5f:


IMAGE ID          REPOSITORY      TAG
0a1b2c3d4e5f      my-app          latest
0a1b2c3d4e5f      my-app          typo_tag
        

Here, my-app:latest and my-app:typo_tag both refer to the same image layers identified by 0a1b2c3d4e5f.

Read: How to Fix ‘ping: command not found’ in Docker Ubuntu Containers

Methods for Removing Docker Image Tags

There isn’t a dedicated docker untag command. Tag removal is typically handled by the docker rmi (remove image) or docker image remove commands, with specific behaviors based on the image’s tagging status.

Tag Removal Methods Comparison

Method 1: Using `docker rmi` When Multiple Tags Point to the Same Image ID

If an image (identified by its unique ID) has more than one tag associated with it, using docker rmi with one of those tags will only remove that specific tag. The underlying image layers will remain because other tags still reference them.

For example, if you tagged an image identified by target_image_identifier incorrectly and then correctly:

# docker tag target_image_identifier my_company/application_suite:erroneous_version_alpha
# docker tag target_image_identifier my_company/application_suite:correct_version_beta

To remove the incorrect tag (my_company/application_suite:erroneous_version_alpha):

# docker rmi my_company/application_suite:erroneous_version_alpha

Executing this command will result in output similar to:

Untagged: my_company/application_suite:erroneous_version_alpha

The image layers (target_image_identifier) persist because my_company/application_suite:correct_version_beta still points to them.

Demonstration with an Example

Let’s illustrate with a fresh image like hello-world:

  1. Pull or ensure the base image exists:
    # docker run hello-world
  2. List current images. You should see hello-world:latest associated with an Image ID. (For the example, let’s assume its Image ID is unique_hello_id_hash).
    # docker images
    REPOSITORY          TAG                 IMAGE ID                  CREATED             SIZE
    hello-world         latest              unique_hello_id_hash      ...                 ...
  3. Create an additional, perhaps mistaken, tag for this image:
    # docker tag hello-world:latest hello-world:temp_label
  4. Listing images now shows both tags pointing to the same Image ID:
    # docker images
    REPOSITORY          TAG                 IMAGE ID                  CREATED             SIZE
    hello-world         latest              unique_hello_id_hash      ...                 ...
    hello-world         temp_label          unique_hello_id_hash      ...                 ...
  5. Remove the temp_label:
    # docker rmi hello-world:temp_label

    Output:

    Untagged: hello-world:temp_label
  6. Verify: The temp_label is gone, but hello-world:latest and its underlying image remain.
    # docker images
    REPOSITORY          TAG                 IMAGE ID                  CREATED             SIZE
    hello-world         latest              unique_hello_id_hash      ...                 ...

Docker Image Lifecycle States

Read: How to Fix ‘Release is not valid yet’ Error During apt-get update in Ubuntu Docker Containers

Method 2: Safely Removing the Last Tag with `docker image remove –no-prune`

A critical situation arises when you want to remove the *only* remaining tag for an image. By default, if you use docker rmi REPOSITORY:TAG on the last tag, Docker will remove the tag *and* the underlying image layers, assuming no other images depend on them. This can lead to unintended data loss if you only wanted to untag the image but keep its layers cached.

To prevent the image layers from being deleted when removing the last tag, use the --no-prune flag with the docker image remove command. Note that docker image remove is often preferred for clarity with newer Docker versions when using such flags, though docker rmi may also support it.

# docker image remove --no-prune your_image_repository/your_image_name:sole_tag_identifier

The --no-prune option ensures that the parent layers of the image are not removed, even if the image becomes untagged. The image will then exist without a human-readable tag but its layers remain in the local Docker cache. It might appear as : in the docker images list but can still be referenced by its Image ID or digest.

Important: If you execute docker rmi your_image_repository/your_image_name:sole_tag_identifier without --no-prune, and this is the sole tag for that specific Image ID, the image itself will likely be deleted. Always double-check if other tags exist for the same Image ID before removing a tag without this protective flag, or use --no-prune if you intend to keep the layers regardless.

Method 3: Reassigning the Tag to Another Image

An alternative, though less direct for typo correction, is to reassign the problematic tag to a different image. This effectively “moves” the tag, thereby removing it from the original image.

  1. Suppose an image (let’s call its ID primary_image_id) is currently tagged as data_processor/service_component:defect_tag_name.
  2. Identify or choose another image, for example, one identified by secondary_image_id or named utility_images/tool:latest_stable.
  3. Execute the following command to reassign the tag:
    # docker tag secondary_image_id data_processor/service_component:defect_tag_name

    Or, if using an existing tag for the source image:

    # docker tag utility_images/tool:latest_stable data_processor/service_component:defect_tag_name

This action updates the data_processor/service_component:defect_tag_name to point to the layers of secondary_image_id (or utility_images/tool:latest_stable). The tag is thus removed from its association with primary_image_id. The primary_image_id and its layers remain, provided they are still referenced by other tags or by their ID.

Consideration for this method: While this detaches the tag from the initial image, the tag itself (potentially a typo) now points to a different image. This might not be the desired outcome if the goal is to completely eliminate the incorrect tag from the system.

It is generally more suitable for scenarios where a tag needs to be deliberately reassigned rather than for correcting simple typographical errors.

Read: How to Fix the Docker Compose `KeyError: ContainerConfig` Error

Verifying Tag Removal

After applying any of the removal methods, you can confirm the outcome by listing your Docker images:

# docker images

Check the output to ensure the specific tag you intended to remove no longer appears. If the image had other tags, it should still be listed with those. If it was the last tag and you used --no-prune, the Image ID should still be present, possibly listed with as repository and tag, but its layers will be preserved.

Key Considerations

  • Default docker rmi behavior: Be mindful that docker rmi REPOSITORY:TAG can remove the image layers if the tag being removed is the last reference to that Image ID and no child images depend on it.
  • The --no-prune safeguard: When you need to remove the final tag but absolutely want to keep the image layers cached, docker image remove --no-prune REPOSITORY:TAG is the recommended approach.
  • Image ID vs. Tag: Always remember that you are removing a *tag* (a pointer). The underlying image layers are only removed if they become unreferenced.

Conclusion

Managing Docker image tags, including removing erroneous or outdated ones, is a routine part of container workflows. While Docker does not offer a direct “untag” command, the docker rmi and docker image remove commands provide the necessary functionality. Understanding that these commands operate on tags, and that image layer removal is a consequence of an image becoming unreferenced, is key.

To avoid accidental deletion of vital image data, developers should use docker rmi judiciously for multi-tagged images and employ the --no-prune flag with docker image remove for last-tag scenarios.

 

Michael Rodriguez

Michael is a Network Engineer and Cloud Infrastructure Specialist with a knack for designing and securing robust network topologies. His experience spans configuring routers, switches, firewalls (both hardware and software like iptables/nftables and Windows Firewall), VPN implementation, and architecting solutions on major cloud platforms like AWS and Azure. He focuses on network performance, reliability, and security best practices in hybrid environments.