Search code examples
dockergithub-actions

Docker invalid reference format (Tag Name) in Github Action


I'm trying to use a build docker image by using same tag from git.

here is the Github Action config

runs-on: ubuntu-latest

steps:
  -
    name: Set up QEMU
    uses: docker/setup-qemu-action@v2
  -
    name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v2
  -
    name: Login to Docker Hub
    uses: docker/login-action@v2
    with:
      username: ${{ secrets.DOCKER_HUB_USERNAME }}
      password: ${{ secrets.DOCKER_HUB_PW }}

  - name: Extract metadata (tags, labels) for Docker
    id: meta
    uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
    with:
      images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}


-
  name: Build and push - with version
  uses: docker/build-push-action@v3
  with:
    context: "{{defaultContext}}"
    push: true
    tags: ${{ steps.meta.outputs.tags }}
    labels: ${{ steps.meta.outputs.labels }}

the current git tag is a0.15.3 ,but when the action was run, it raise error

ERROR: invalid tag "/:a0.15.3": invalid reference format

why there is extra prefix "/: ? is this prefix causing the error ? how to fix this in the Github Action Workflow file ?

/usr/bin/docker buildx build --iidfile /tmp/docker-build-push-vwhSgm/iidfile --label org.opencontainers.image.title=XXXX
--label org.opencontainers.image.description=XXXX --label org.opencontainers.image.url=https://github.com/***/XXXX--label org.opencontainers.image.source=https://github.com/***/XXXX--label org.opencontainers.image.version=a0.15.3 --label org.opencontainers.image.created=2023-05-04T04:49:01.011Z --label org.opencontainers.image.revision=d450d4dce21b38b6091e6ebe3bfa8f6ede553816 --label org.opencontainers.image.licenses=BSD-3-Clause --provenance false --secret id=GIT_AUTH_TOKEN,src=/tmp/docker-build-push-vwhSgm/tmp-40371-OFYmqDXttfTp --tag /:a0.15.3 --tag /:latest --metadata-file /tmp/docker-build-push-vwhSgm/metadata-file --push https://github.com/***/XXXX.git#d450d4dce21b38b6091e6ebe3bfa8f6ede553816
ERROR: invalid tag "/:a0.15.3": invalid reference format
Error: buildx failed with: ERROR: invalid tag "/:a0.15.3": invalid reference format


Solution

  • tl;dr

    • What you cannot break was not for real.
    • Have adequate defaults, always.
    • Handle input parameters of an action that errors with scrutiny.

    The error message:

    ERROR: invalid tag "/:a0.15.3": invalid reference format
    

    is emitted from the docker/metadata-action action and caused by a configuration issue in your workflow steps entry with the id "meta", specifically this part:

          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
    

    With the workflows step env context the error message shows both context properties, REGISTRY and IMAGE_NAME, empty, resulting in the invalid tag "/:a0.15.3".

    What you then consider the "extra prefix "/: [sic!]" is actually the workflows' author commandment to forcefully use even an empty Docker registry name and an empty Docker image name (which is a good scenario to test for failure btw.).

    Out of the blue, I would guess this is just because the jobs.<job_id>.steps[*].envor similar in the hierarchy have the REGISTRY and IMAGE_NAME properties undefined (at least the excerpt of the workflow in question — which may be inherited — does not have any definitions of this kind).

    This is obviously only a small (but still an) error of the docker/metadata-action Microsoft Github Action steps' image configuration setting as it is required and must contain a valid docker image name as otherwise the action can not generate a valid docker image tag name from it.

    The error message emitted by the action could be improved thought as in your case it created the impression the tag-name would be wrong while it can be clearly said, that the image name - input of the action - was already invalid. So it looks like that this action does not validate its inputs prior use, which puts this onto the responsibility of its users. If you feel the same, do not expect this to be different, as the action documents this behaviour, but instead make use of the license and contribute back to the project.

    Successfully Configure the Docker Image Name for the Docker Metadata Github Action

    Let us unfold this little, but still a configuration problem after all and inspect its inner parts and workings to gain enough understanding of the problem in question, so that a good answer on how to configure this and similar workflows can be given.

    Configuration of the Docker Registry

    You're logging into the default docker registry, which is "docker.io"¹, therefore this is the first REGISTRY environment parameters default value meaning. It needs to be used, you cannot just pass an empty string. Therefore, cover the default when creating the input for the docker metadata action, as we already have found out that it does not handle that case well:

          images: ${{ env.REGISTRY || "docker.io" }}/${{ env.IMAGE_NAME }}
    

    Example: Use of the or operator (||²) in an expression to fall-through to a default value:

    ${{ env.REGISTRY || "docker.io" }}: If env.REGISTRY is empty or undefined, then use "docker.io" instead.³

    As you're using the default registry, you could also leave it out, but you then would require to also remove the inner slash ("/") (e.g.: images: ${{ env.IMAGE_NAME }}), but I do not suggest that in context of your question, as the default value "docker.io" may also be unintended, and therefore you can replace it with your intended default value easier.

    Configuration of the Docker Image Name

    And you have not shared in your question what the default value of the IMAGE_NAME environment parameter is. For the completeness of the answer so far, lets just assume it is the Github owner and repository name, which will complete the input and gives the example again on how to provide a default value, this time from the github context:

          images: ${{ env.REGISTRY || "docker.io" }}/${{ env.IMAGE_NAME || github.repository }}
    

    Given yours would be the acme owners' hello-world repository on Github, the image-name that tag would be prefixed with by the metadata action then would become in that scenario:

    docker.io/acme/hello-world:a0.15.3
    

    Instead of using the github.repository expression as default, you can naturally formulate any other expression, as long as it is a string of valid syntax for the docker image name component in a docker image name (next).

    Syntax of the Docker Image Name Component

    That is the syntax of the Docker image name components for images of the Docker Metadata Github Action and Docker in general:

    An image name is made up of slash-separated name components, optionally prefixed by a registry hostname. [...]

    Name components may contain lowercase letters, digits and separators. A separator is defined as a period, one or two underscores, or one or more dashes. A name component may not start or end with a separator. [...]

    image-name            ::= prefix? name-components
    ...
    name-components       ::= name-component ( "/" name-component )?
    name-component        ::= name ( name-separator name )*
    name                  ::= [a-z0-9]+
    name-separator        ::= ( "." | "_" "_"? | "-"+ )
    

    (excerpts from: Docker Container (Image/Tag) Name Syntax)

    In your specific case, I'm somewhat certain that you know the default name already, it was just that the issue was you expected it being the IMAGE_NAME environment parameter already, but then it has not been initialized yet.

    Quick Fix Trouble Shooting the Image Name in the Docker Metadata Microsoft Github Action

    Therefore, you may want to use a different default value here, and if it is only a hardcoded string for configuration testing:

          images: ${{ env.REGISTRY || "docker.io" }}/${{ env.IMAGE_NAME || "my-name-of-docker-image" }}
    

    That example to get a quick fix running. Replace it (image name "my-name-of-docker-image") or both (also default registry "docker.io") with the correct default values from the appropriate contexts then.

    Default Environment in and for the Workflow and its Steps

    Or set their default values in the env context in the first place, which requires more work, e.g. defining the environment variables for the workflow:

    env:
      REGISTRY: docker.io
      IMAGE_NAME: my-name-of-docker-image
    

    Defining an env at the workflow top level has the benefit that the environment variables are initially set for the whole workflow jobs, that also includes in the jobs.<job_id>.steps[*].env context of yours, where those two parameters (env.REGISTRY and env.IMAGE_NAME) are currently undefined or empty.

          # safe use of context parameters as defaults are set up before:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
    

    Often, correct defaults are self-documenting, too. If possible, place them at the top of the file or the beginning of the part they are introduced for.

    tl;dr

    • What you cannot break was not for real.
    • Have adequate defaults, always.
    • Handle input parameters of an action that errors with scrutiny.

    ¹ c.f. answer of "Where Docker default registry URL is configured?"

    ² c.f. Operators - Expressions (Learn GitHub Actions)

    ³ c.f. answer of "How to use env variable as default value for input in GitHub actions?"