Skip to content

ARG interpolation behaves differently in multilayer builds #6648

@drmoose

Description

@drmoose

Issue Description

An ARG set in a parent layer as a quoted string, ARG quoted="words with quotes" and then interpolated in a RUN as RUN echo $quoted will expand to RUN echo words with quotes on the layer that declared the ARG, but in subsequent layers of a multi-stage build will expand to RUN echo \"words with quotes\", which differs from the current docker build behavior.

Steps to reproduce the issue

Adding the following conformance test to tests/conformance fails:

// tests/conformance/conformance_test.go
	{
		name:         "quoted-arg",
		dockerfile:   "Dockerfile.quoted-arg",
		fsSkip:       []string{"(dir):arg-expansion.txt:mtime"},
	},
# tests/conformance/testdata/Dockerfile.quoted-arg
FROM quay.io/libpod/centos:7 AS lower

ARG quoted="words with quotes"

RUN printf "%q\n" lower: $quoted >> /arg-expansion.txt

FROM lower AS upper

RUN printf "%q\n" upper: $quoted >> /arg-expansion.txt

Describe the results you received

podman run $(podman build -q - < tests/conformance/testdata/Dockerfile.quoted-arg) cat /arg-expansion.txt says:

lower:
words
with
quotes
upper:
\"words
with
quotes\"

Suggesting something is implicitly escaping the quotes rather than simply inserting them verbatim.

Describe the results you expected

docker run $(docker build -q - < tests/conformance/testdata/Dockerfile.quoted-arg) cat /arg-expansion.txt says:

lower:
words
with
quotes
upper:
words
with
quotes

ie, the "lower:" and "upper:" results are the same, and the unquoted variable is behaving like a normal shell variable

buildah version output

Version:         1.42.2
Go Version:      go1.25.5 X:nodwarf5
Image Spec:      1.1.1
Runtime Spec:    1.2.1
CNI Spec:        1.1.0
libcni Version:  v1.3.0
image Version:   5.38.0
Git Commit:      c0cc97255c76f7a3d87bfdf5e7b97f013f0bfe85
Built:           Wed Dec  3 08:00:04 2025
OS/Arch:         linux/amd64
BuildPlatform:   linux/amd64

buildah info output

{
    "host": {
        "CgroupVersion": "v2",
        "Distribution": {
            "distribution": "arch",
            "version": "unknown"
        },
        "MemFree": 12951314432,
        "MemTotal": 134965145600,
        "OCIRuntime": "crun",
        "SwapFree": 127345881088,
        "SwapTotal": 140660174848,
        "arch": "amd64",
        "cpus": 32,
        "hostname": "jeeves",
        "kernel": "6.11.9-arch1-1",
        "os": "linux",
        "rootless": true,
        "uptime": "1072h 46m 2.57s (Approximately 44.67 days)",
        "variant": ""
    },
    "store": {
        "ContainerStore": {
            "number": 9
        },
        "GraphDriverName": "overlay",
        "GraphImageStore": "",
        "GraphOptions": null,
        "GraphRoot": "/home/drmoose/.local/share/containers/storage",
        "GraphStatus": {
            "Backing Filesystem": "btrfs",
            "Native Overlay Diff": "true",
            "Supports d_type": "true",
            "Supports shifting": "false",
            "Supports volatile": "true",
            "Using metacopy": "false"
        },
        "GraphTransientStore": false,
        "ImageStore": {
            "number": 65
        },
        "RunRoot": "/run/user/1000/containers"
    }
}

Provide your storage.conf

I don't have a storage.conf in `/home/drmoose/.config`, but here's the `/etc` one:


[storage]
driver = "overlay"
runroot = "/run/containers/storage"
graphroot = "/var/lib/containers/storage"
[storage.options]
additionalimagestores = [
]
[storage.options.pull_options]
[storage.options.overlay]
mountopt = "nodev"

Upstream Latest Release

Yes

Additional environment details

Additional environment details

Additional information

The container docker builds for me (shown above) doesn't match the container docker builds for the conformance tester, which does a third, even weirder thing: stripping out the ARG value entirely in the lower layer. I haven't dug into conformance_test.go in enough depth to speculate why this might be.

$ docker run --rm -it conformance-docker:1769011616845381084-3 cat /arg-expansion.txt
lower:
words
with
quotes
upper:

Workaround

Adding ENV quoted=$quoted directly below the ARG line passes the test, with both docker and podman returning the correct strings.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions