Skip to content

Flux Kustomization's spec.images with newName strips existing image tags #5787

@nerahou

Description

@nerahou

Describe the bug

When using Flux Kustomization's spec.images field with only newName (without newTag), it strips the image tag that was already set in the base kustomization, resulting in an untagged (:latest) image reference.

This is inconsistent with how plain kustomize behaves when applying an overlay that only changes the image name.

Steps to reproduce

1. Create a base kustomization with an image tag

base/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
images:
  - name: ghcr.io/example/myapp
    newTag: v1.2.3

2. Build with plain kustomize - tag is present ✓

$ kustomize build base | grep "image:"
        image: ghcr.io/example/myapp:v1.2.3

3. Use kustomize images to change registry

kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - base
images:
  - name: ghcr.io/example/myapp
    newName: my-registry/my-app

4. Build with Kustomize - tag is present ✓

$ kustomize build | grep "image:"                                                    
      - image: my-registry/my-app:v1.2.3

5. Use Flux Kustomization with spec.images to change registry

flux-kustomization.yaml:

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: myapp
  namespace: default
spec:
  path: ./base
  images:
    - name: ghcr.io/example/myapp
      newName: registry.example.com/myapp
  # ... other fields

6. Build with Flux - tag is LOST ✗

$ flux build kustomization myapp --path ./base --kustomization-file ./flux-kustomization.yaml --dry-run | grep "image:"
        image: registry.example.com/myapp

Expected: registry.example.com/myapp:v1.2.3
Actual: registry.example.com/myapp (no tag)

Workaround

Use a component to set the tag:

components/version/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
images:
  - name: ghcr.io/example/myapp
    newTag: v1.2.3

Reference it in Flux Kustomization:

spec:
  path: ./base
  components:
    - ../components/version
  images:
    - name: ghcr.io/example/myapp
      newName: registry.example.com/myapp

This preserves the tag, but requires duplicating the version.

Analysis

The issue appears to be in how spec.images processes image transformations:

  1. Base kustomization produces: ghcr.io/example/myapp:v1.2.3
  2. Flux's spec.images with only newName strips the tag
  3. However, if the tag comes from a component, it's preserved when newName is applied

This suggests the bug is in the order/timing of transformations or how spec.images handles existing tags from the built manifests.

Expected behavior

When spec.images specifies only newName to change the image registry/repository, it should preserve the existing tag from the base kustomization output.

This is consistent with how plain kustomize behaves when applying an overlay that only changes the image name.

Screenshots and recordings

No response

OS / Distro

macOS 26.2

Flux version

flux: v2.6.4

Flux check

► checking prerequisites
✗ flux 2.6.4 <2.8.3 (new CLI version is available, please upgrade)
✔ Kubernetes 1.33.8-eks-f69f56f >=1.31.0-0
► checking version in cluster
✔ distribution: flux-2.7.5
✔ bootstrapped: false
► checking controllers
✔ helm-controller: deployment ready
► ghcr.io/fluxcd/helm-controller:v1.4.5
✔ kustomize-controller: deployment ready
► ghcr.io/fluxcd/kustomize-controller:v1.7.3
✔ source-controller: deployment ready
► ghcr.io/fluxcd/source-controller:v1.7.4
► checking crds
✔ buckets.source.toolkit.fluxcd.io/v1
✔ externalartifacts.source.toolkit.fluxcd.io/v1
✔ gitrepositories.source.toolkit.fluxcd.io/v1
✔ helmcharts.source.toolkit.fluxcd.io/v1
✔ helmreleases.helm.toolkit.fluxcd.io/v2
✔ helmrepositories.source.toolkit.fluxcd.io/v1
✔ kustomizations.kustomize.toolkit.fluxcd.io/v1
✔ ocirepositories.source.toolkit.fluxcd.io/v1
✔ all checks passed

Git provider

No response

Container Registry provider

No response

Additional context

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions