Description
What happened:
❯ cat test.env
TEST_STRING_1=hello
TEST_STRING_2="hello world"
TEST_STRING_3='hello world'
❯ kubectl create configmap test --from-env-file test.env
configmap/test created
❯ k get cm test -o yaml
apiVersion: v1
data:
TEST_STRING_1: hello
TEST_STRING_2: '"hello world"'
TEST_STRING_3: '''hello world'''
kind: ConfigMap
metadata:
creationTimestamp: "2025-06-20T05:47:06Z"
name: test
namespace: default
resourceVersion: "210905"
uid: 254eced4-4dd9-4abc-8567-90b647f4186b
❯ source test.env
❯ echo $TEST_STRING_1
hello
❯ echo $TEST_STRING_2
hello world
❯ echo $TEST_STRING_3
hello world
❯ kubectl get cm test -o jsonpath='{.data.TEST_STRING_1}'
hello
❯ kubectl get cm test -o jsonpath='{.data.TEST_STRING_2}'
"hello world"
❯ kubectl get cm test -o jsonpath='{.data.TEST_STRING_3}'
'hello world'
What you expected to happen:
The expected behavior for environment files is that they would allow quotation handling in the same manner as POSIX shell environments, i.e. such that the resulting values in the evaluated config map would instead be:
❯ k get cm test -o yaml
apiVersion: v1
data:
TEST_STRING_1: hello
TEST_STRING_2: hello world
TEST_STRING_3: hello world
kind: ConfigMap
metadata:
creationTimestamp: "2025-06-20T05:47:06Z"
name: test
namespace: default
resourceVersion: "210905"
uid: 254eced4-4dd9-4abc-8567-90b647f4186b
❯ source test.env
❯ echo $TEST_STRING_1
hello
❯ echo $TEST_STRING_2
hello world
❯ echo $TEST_STRING_3
hello world
❯ kubectl get cm test -o jsonpath='{.data.TEST_STRING_1}'
hello
❯ kubectl get cm test -o jsonpath='{.data.TEST_STRING_2}'
hello world
❯ kubectl get cm test -o jsonpath='{.data.TEST_STRING_3}'
hello world
The current behavior means that quotations required within a POSIX shell environment are interpreted literally by the kubectl tool, which means that it is not possible to use the same environment files within both the context of a POSIX shell environment and with the kubectl tool. This both breaks the expected feature set of environment files for the user, and will require separate files or special handling by the user, instead of being able to re-use existing files.
How to reproduce it (as minimally and precisely as possible):
See above.
Anything else we need to know?:
There is a related issue for the kustomize tool, ideally both tools should be fixed in the same manner to ensure consistent behavior using a more complete environment file parser.
kubernetes-sigs/kustomize#4525
Note that a parser such as https://github.com/joho/godotenv will correctly parse quoted strings, see:
- https://github.com/joho/godotenv/blob/main/godotenv_test.go
- https://github.com/joho/godotenv/blob/main/fixtures/quoted.env
Environment:
- Kubernetes client and server versions (use
kubectl version
):
❯ kubectl version
Client Version: v1.33.0
Kustomize Version: v5.6.0
Server Version: v1.31.0
- Cloud provider or hardware configuration: local
- OS (e.g:
cat /etc/os-release
):
❯ cat /etc/os-release
ANSI_COLOR="0;38;2;126;186;228"
BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
BUILD_ID="25.05.20250522.55d1f92"
CPE_NAME="cpe:/o:nixos:nixos:25.05"
DEFAULT_HOSTNAME=nixos
DOCUMENTATION_URL="https://nixos.org/learn.html"
HOME_URL="https://nixos.org/"
ID=nixos
ID_LIKE=""
IMAGE_ID=""
IMAGE_VERSION=""
LOGO="nix-snowflake"
NAME=NixOS
PRETTY_NAME="NixOS 25.05 (Warbler)"
SUPPORT_END="2025-12-31"
SUPPORT_URL="https://nixos.org/community.html"
VARIANT=""
VARIANT_ID=""
VENDOR_NAME=NixOS
VENDOR_URL="https://nixos.org/"
VERSION="25.05 (Warbler)"
VERSION_CODENAME=warbler
VERSION_ID="25.05"