DEV Community

Rasika Dangamuwa
Rasika Dangamuwa

Posted on

Why JSON to YAML Conversion Fails in Production: The Norway Problem & 5 Subtle Traps

Every DevOps engineer has spent hours debugging a CI/CD pipeline failure only to discover the root cause was a single unquoted word in a YAML file. We often treat JSON and YAML as interchangeable formats—YAML 1.2 is even formally a superset of JSON.

Yet when converting JSON configuration payloads (API configs, Docker Compose files, Kubernetes manifests, or Helm charts) into YAML, subtle serialization differences silently corrupt production data.

Here are 5 traps that occur when converting JSON to YAML, why they happen, and how to prevent them.


1. The Classic "Norway Problem" (YAML 1.1 Boolean Coercion)

In JSON, data types are strict:

{
  "country": "NO",
  "enabled": true,
  "flag": "yes"
}
Enter fullscreen mode Exit fullscreen mode

However, many production parsers (such as Python's PyYAML, older Ruby parsers, and various Helm engines) default to the YAML 1.1 specification. Under YAML 1.1, unquoted strings matching boolean aliases are coerced:

  • y, Y, yes, Yes, YES -> true
  • n, N, no, No, NO -> false
  • on, off -> true, false

Without strict string quoting during conversion:

country: NO
enabled: true
flag: yes
Enter fullscreen mode Exit fullscreen mode

A YAML 1.1 engine parses country: NO as {"country": false}. An application routing traffic by ISO country code fails to recognize Norway, and flag: yes becomes a boolean.

Fix: Always wrap ISO codes and boolean-like strings in quotes: country: "NO".


2. Octal Numbers and Leading Zeros

In JSON (RFC 8259), numbers cannot have leading zeros; identifiers or permissions are stored as strings ("0755", "02134").

In YAML 1.1, integers with leading zeros are parsed as octal:

# Intended: File permission 0755
permissions: 0755   # Evaluates to decimal 493!
zip_code: 02134      # Evaluates to decimal 1116!
Enter fullscreen mode Exit fullscreen mode

While YAML 1.2 requires the 0o prefix (e.g. 0o755), legacy parsers mangle unquoted numbers with leading zeros into unintended integers.

Fix: Enforce explicit quotes on all identifiers, zip codes, and file modes: permissions: "0755".


3. Sexagesimal (Base-60) Time Coercion

YAML 1.1 supports sexagesimal (base-60) notation. If JSON contains time strings like HH:MM:

{
  "maintenance_window": "12:30",
  "build_timeout": "1:45:00"
}
Enter fullscreen mode Exit fullscreen mode

Converted to unquoted YAML:

maintenance_window: 12:30    # Parsed as integer: 750
build_timeout: 1:45:00       # Parsed as integer: 6300
Enter fullscreen mode Exit fullscreen mode

The parser computes (12 * 60) + 30 = 750 seconds. Services expecting a time string crash with type errors or set a 12-minute timeout instead of 12:30 PM.

When converting complex JSON configs to YAML, using a dedicated browser-based tool like the Nutilz JSON to YAML Converter lets you inspect quotes, enforce 2-space or 4-space indentation, sort object keys deterministically, and test syntax validation without sending configuration tokens to remote servers.


4. Multiline String Chomping (| vs > vs |-)

JSON stores multiline strings with explicit \n sequences:

{
  "nginx_conf": "server {\n  listen 80;\n  server_name app.internal;\n}"
}
Enter fullscreen mode Exit fullscreen mode

In YAML, choosing the wrong scalar style breaks nginx configs, shell scripts, or certificates:

  • Literal (|): Preserves newlines as written (ideal for scripts and certs).
  • Folded (>): Replaces newlines with spaces (breaks config blocks).
  • Chomping strip (|-): Strips trailing newlines.
# Correct for configs and scripts:
nginx_conf: |
  server {
    listen 80;
    server_name app.internal;
  }
Enter fullscreen mode Exit fullscreen mode

5. Nulls vs Empty Strings vs Omitted Keys

In JSON, null and "" are distinct:

{
  "field_null": null,
  "field_empty": ""
}
Enter fullscreen mode Exit fullscreen mode

In YAML:

field_null: ~
field_empty: ""
Enter fullscreen mode Exit fullscreen mode

If a converter emits bare field_null: without ~ or null, some parsers resolve it as "" and others as null. Round-tripping back to JSON can mutate null into an empty string, breaking if (val === null) checks.

Fix: Use explicit "" for empty strings and null or ~ for null values.


Summary Checklist

  1. Quote boolean strings: "yes", "no", "NO", "true", "false".
  2. Quote leading-zero strings: "0755", "02138".
  3. Use literal block scalars (|) for shell commands and multiline configs.
  4. Target YAML 1.2, but verify if downstream tooling (Helm/PyYAML) applies YAML 1.1 rules.
  5. Verify round-trip parity between JSON and YAML before deploying to production.

Whether migrating CloudFormation templates, building Helm charts, or debugging GitHub Actions matrices, understanding YAML type coercion keeps deployments predictable. For fast, privacy-friendly schema conversion and formatting right in your browser, check out the Nutilz JSON to YAML Converter.

Top comments (0)