With Kubernetes 1.35, KYAML moved to beta and was enabled by default as a new output format for kubectl. The intent is clear: reduce ambiguity, improve safety, and avoid long-standing YAML footguns like implicit typing.
On paper, that sounds reasonable.
In practice, I think KYAML is a mistake.
This post isn’t meant to be inflammatory, and I fully understand why KYAML exists. But after looking at the format, using it, and thinking about where it fits in the broader configuration ecosystem, I don’t see a legitimate use case where KYAML is the right answer.
What problem is KYAML trying to solve?
KYAML exists primarily to address YAML ambiguity. The canonical example is the so-called “Norway problem,” where values like:
enabled: NO
are interpreted as booleans instead of strings. KYAML avoids this by enforcing:
- quoted strings
- explicit {} maps and [] lists
- a restricted, predictable subset of YAML
The goal is to make Kubernetes configuration:
- safer
- less surprising
- more machine-friendly
These are all valid goals, but here’s the key question: Is this problem big enough to justify a new format?
In my view, no.
The ambiguity problem is real — but overstated
Yes, YAML’s implicit typing can surprise people. Yes, NO, YES, ON, timestamps, and numbers can bite you, but in real-world Kubernetes usage, this is a known issue, it is well-documented, and it is easy to avoid with basic discipline
Just quote your strings, and treat YAML as data, not prose, and lint your manifests.
This is not a systemic failure — it’s a sharp edge that experienced users already understand, and solving only this problem does not justify introducing an entirely new representation style.
KYAML takes the worst parts of JSON and YAML
This is my core objection.
KYAML combines JSON’s visual noise ({}, [], commas everywhere), with YAML’s complexity and special rules without fully embracing the strengths of either
- If you dislike whitespace sensitivity – use JSON
- If you want human-readable configuration – use YAML
KYAML sits awkwardly in the middle. It looks like JSON, but it isn’t JSON, it parses as YAML, but it doesn’t feel like YAML. Calling it “just YAML” is technically correct — but practically misleading.
“Technically valid YAML” is not the same as “usable YAML”
One of the most common defenses of KYAML is:
“It’s still YAML. Any YAML parser can read it.”
That’s true — and also irrelevant. Formats are not just about parsers. They’re about readability, ergonomics, familiarity,and how humans reason about structure.
KYAML does not look like YAML, it does not read like YAML, and it does not behave like YAML in the ways people care about.
If I showed a KYAML manifest to someone and asked “what format is this?”, almost no one would answer “YAML” without context, and that disconnect matters.
Human readability still matters — a lot
Kubernetes configuration is read far more often than it is written, on-call engineers, debug sessions, quick reviews, copy/paste fixes, teaching and documentation, etc.
Block-style YAML excels here:
containers:
- name: api
image: nginx:v1
ports:
- containerPort: 8080
KYAML does not:
containers: [
{
name: "api",
image: "nginx:v1",
ports: [{ containerPort: 8080 }],
},
]
This is denser, noisier, and harder to scan, especially at scale. And multi-line strings? They become actively painful.
For a system that routinely embeds scripts, configs, policies, and templates inside manifests, this is a serious issue in my mind.
As one reddit commentor put it:
It’s basically JSON with trailing commas and comment support… annoying quotes, commas and brackets? No thanks.
Multi-line strings are where KYAML really falls apart
One area where KYAML’s weaknesses become impossible to ignore is multi-line strings.
Kubernetes manifests frequently embed shell scripts, application configuration files, policy documents, JSON blobs, NGINX, Envoy, or HAProxy configs, etc.
This is exactly where block-style YAML shines.
Block YAML: readable and intention-revealing
With standard YAML, multi-line content is explicit, readable, and easy to reason about:
data:
startup.sh: |
#!/bin/sh
set -e
echo "Starting application"
exec /app/server
At a glance, it’s obvious where the string starts, where it ends, what belongs to it, and what does not.
This is one of YAML’s biggest strengths as a human-oriented configuration format.
KYAML: dense, noisy, and hostile to humans
The same content in KYAML-style flow syntax becomes significantly harder to read and edit:
data: {
startup.sh: "#!/bin/sh\nset -e\n\necho \"Starting application\"\nexec /app/server\n",
}
This has several practical downsides:
- Newlines are hidden behind escape sequences
- Quoting and escaping noise overwhelms the content
- Editing becomes error-prone
- Diff reviews become painful
- Copy/paste workflows degrade badly
At this point, the configuration stops being something you read and becomes something you decode. This is not an edge case, multi-line strings are not rare in Kubernetes, they are everywhere from ConfigMaps, Secrets (before base64), init scripts, policy engines, sidecar configs, templated applications, etc.
A format that makes this use case worse is a poor fit for Kubernetes in practice.
Even supporters of KYAML have acknowledged this weakness. As one Reddit commenter put it:
“I think I like everything except for multi-line strings… this just seems so obnoxious.”
That reaction is telling. If a format fails at one of Kubernetes’ most common real-world patterns, that’s not a minor flaw, it’s a fundamental mismatch.
Readability matters more than theoretical safety here. Yes, KYAML avoids certain ambiguity issues, but in exchange, it degrades one of the most valuable properties of YAML: clear, readable representation of structured text.
For me, this alone is enough to disqualify KYAML as a default or recommended format for Kubernetes manifests.
If YAML isn’t enough, KYAML isn’t the answer
Here’s where I think the Kubernetes ecosystem already has better answers.
If you want stronger typing, validation, composition, abstraction, and safety guarantees, then configuration languages make sense like KCL, Carvel YTT, Cue, etc.
These tools solve real problems, large-scale config management, reusability, correctness, policy enforcement, etc. and KYAML does none of this. It doesn’t add expressiveness, it doesn’t add validation, and it doesn’t add abstraction. It only changes formatting.
If we’re going to introduce something new, it should meaningfully improve what we can do — not just how braces are arranged.
“But it’s better for machines”
This is the strongest argument in favor of KYAML, and even here, I’m unconvinced.
If the goal is machine-friendliness, JSON already exists, is unambiguous, is universally supported, and is widely understood.
I regularly switch to JSON precisely because I want to avoid whitespace sensitivity. KYAML simply adds complexity without gaining the clarity of a true data format.
Where I land
I don’t believe KYAML has a compelling use case.
It doesn’t replace YAML for humans, it doesn’t replace JSON for machines, and it doesn’t replace higher-level config languages for safety or scale
It solves a narrow problem that already has known, simple mitigations — and in doing so, creates new ergonomic and cognitive costs.
This all being said, it doesn’t mean it won’t see adoption. Kubernetes has enormous gravity, and defaults matter.
But from my perspective, KYAML feels like a format born from good intentions, solving the wrong problem, at the wrong layer.
Summary
It will be interesting to see whether the industry embraces it or not.
I have yet to meet a person who truely likes this new format but I know many are out there, just like many people believe go-templating and jsonnet are good choices, and I don’t.
I do still like that Kubernetes supports normal YAML, and JSON for input and output so I am not against the notion of having another option, I just think this option is worse then what we already have, so it makes no sense to me why we are investing in it at all.
KYAML is a well-intentioned experiment. As an optional output format, it has some value — especially for tools that need predictable structure. But as a default manifest representation, it fails the core requirement of being human-friendly and intuitive.
It fixes one specific YAML footgun at the cost of introducing a format most people will honestly hate reading. Worse, it doesn’t actually solve the deeper problems that make Kubernetes configuration hard at scale.
I’m not anti-improvement. I just think this isn’t the improvement we needed.
If the industry truly wants safer, more robust configs, we should embrace type-safe config languages, schema-aware tooling, and problem-focused ergonomics — not yet another YAML dialect that looks like JSON but behaves worse for humans.
