-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Issue Description
Any HealthCmd value in a Quadlet .container file that contains shell metacharacters (single quotes ', brackets []) produces /bin/sh: syntax error: unterminated quoted string at runtime. The identical command works correctly when run via podman exec or directly on the command line.
The only working workaround is moving the command to an external shell script and referencing it as the HealthCmd value.
Steps to reproduce the issue
- Create a Quadlet
.containerfile with any of the followingHealthCmdvalues:
# Attempt 1 — single quotes
HealthCmd=/bin/sh -c "netbird status | grep -q 'Management: Connected'"
# Attempt 2 — escaped double quotes
HealthCmd=/bin/sh -c "netbird status | grep -q \"Management: Connected\""
# Attempt 3 — hex escape for single quote
HealthCmd=/bin/sh -c "netbird status | grep -q \x27Management: Connected\x27"
# Attempt 4 — POSIX character class (brackets)
HealthCmd=/bin/sh -c "netbird status | grep -qE Management:[[:space:]]+Connected"
# Attempt 5 — pipe with no quotes
HealthCmd=/bin/sh -c "netbird status | grep Management | grep -qv Not"- Reload and start:
systemctl --user daemon-reload
systemctl --user start <service>.service- Inspect health state:
podman inspect <container> --format "{{json .State.Health}}" | python3 -m json.toolDescribe the results you received
All attempts above produce the same failure:
{
"Status": "unhealthy",
"Log": [{
"Start": "2026-03-29T20:02:35.565735588+02:00",
"End": "2026-03-29T20:02:35.668385384+02:00",
"ExitCode": 1,
"Output": "/bin/sh: syntax error: unterminated quoted string\n"
}]
}The same commands execute without error when run directly:
podman exec <container> /bin/sh -c "netbird status | grep -q 'Management: Connected'"
# Exit code: 0 ✓Describe the results you expected
Healthcheck executes successfully. Exit code 0 when the expected string is present in command output.
podman info output
host:
arch: amd64
buildahVersion: 1.39.3
cgroupControllers:
- cpu
- memory
- pids
cgroupManager: systemd
cgroupVersion: v2
conmon:
package: conmon_2.1.12-4_amd64
path: /usr/bin/conmon
version: 'conmon version 2.1.12, commit: unknown'
distribution:
codename: trixie
distribution: debian
version: "13"
kernel: 6.12.74+deb13+1-amd64
networkBackend: netavark
networkBackendInfo:
package: netavark_1.14.0-2_amd64
version: netavark 1.14.0
ociRuntime:
name: crun
package: crun_1.21-1_amd64
version: crun version 1.21
rootlessNetworkCmd: pasta
security:
rootless: true
selinuxEnabled: false
version:
APIVersion: 5.4.2
BuildOrigin: Debian
Version: 5.4.2Podman in a container
No
Privileged Or Rootless
Rootless
Upstream Latest Release
Yes
Additional environment details
podman version: 5.4.2 (BuildOrigin: Debian)
OS: Debian GNU/Linux 13 (trixie)
kernel: 6.12.74+deb13+1-amd64
arch: amd64
rootless: true
cgroupManager: systemd
cgroupVersion: v2
ociRuntime: crun 1.21
networkBackend: netavark 1.14.0
conmon: 2.1.12
Additional information
Potential Root Cause
The HealthCmd value passes through two parsing layers before the shell inside the container sees it:
HealthCmd INI value (raw text)
↓
systemd INI parser ← Layer 1: treats " and ' as its own string delimiters
↓
podman --health-cmd "..." ← receives mangled string
↓
/bin/sh -c "..." ← Layer 2: receives broken string, fails
The systemd INI parser interprets "..." as its own quoted string and strips the outer double quotes. Any remaining shell metacharacters (', [, ]) are then reinterpreted by the systemd parser's own rules — not passed through verbatim to the shell.
Running the command in a terminal bypasses Layer 1 entirely, which is why it works there.
Workaround
Option 1
Use CMD-SHELL for shell execusion:
HealthCmd=CMD-SHELL netbird status | grep -q 'Management: Connected'Option 2
Move the command to an external script and reference it:
cat > /path/to/healthcheck.sh << 'EOF'
#!/bin/sh
netbird status | grep -q 'Management: Connected'
EOF
chmod +x /path/to/healthcheck.shHealthCmd=/path/to/healthcheck.shRelated Issues
- quadlet fails to handle quoting properly in
.containerfiles #20992 — General Quadlet quoting problems (partially fixed; this case remains broken in 5.4.2) - [Quadlet] HealthCmd failing if there is no shell #25729 —
HealthCmdfailing without shell