Sitemap

Avoid YAML Pitfalls: Use File Descriptors and Quote Your Variables

2 min readAug 1, 2025

In the process of upgrading our internal tooling, we uncovered two important best practices that will help you avoid subtle and frustrating issues when working with Helm, Docker, CI/CD, or any system that deals with environment variables and YAML-based configurations.

Let’s walk through what happened and how to fix it: the right way.

Use File Descriptors Instead of Symbols

We encountered this issue when we upgraded helmfile to a newer version. This brought in stricter YAML parsing behavior, which surfaced a parsing error when trying to apply one of our Helm charts.

Here’s the stack trace we encountered:

cutting template expressions in release "app-dev":
failed cloning release "app-dev": [643:26] block sequence entries are not allowed in this context
640 | schedule: 0 23 * * 6
641 | - env:
642 | ENVIRONMENT: dev
> 643 | GUNICORN_ACCESS_LOG: -
^
644 | GUNICORN_ERROR_LOG: -
645 | GUNICORN_PORT: '8080'
646 | GUNICORN_WORKER_COUNT: '2'

The issue? YAML misinterpreted the - symbol as a block sequence indicator rather than a string value.

The Fix

Replace the ambiguous - with a clear, POSIX-compliant file descriptor path:

- name: GUNICORN_ACCESS_LOG
value: "/proc/self/fd/1"
- name: GUNICORN_ERROR_LOG
value: "/proc/self/fd/2"

This is functionally equivalent (still stdout/stderr), but it avoids YAML parsing issues and is much clearer to anyone reading your configuration.

Why This Matters

  • Prevents unexpected YAML parsing errors
  • Adheres to POSIX standards (universally supported)
  • Self-documenting — avoids confusion about what - means
  • Works across tooling: Helm, Docker, apps, CI/CD, etc.

Where You Should Apply This

Update all places where you define log output streams:

  • Helm charts
  • Dockerfiles
  • Application configs
  • Shell scripts or entrypoints
  • CI/CD configuration files

Unless you’re writing logs to a specific file, always use /proc/self/fd/1 and /proc/self/fd/2 for stdout and stderr.

Always Quote Your Variables

Another common issue we’ve seen (and corrected recently) is unquoted variables in YAML or shell configs, especially those containing special characters like dots, dashes, asterisks, or colons.

Don’t do this:

APP_SERVER_ADDRESS: app.dev.internal.company.com:7283

Do this instead:

APP_SERVER_ADDRESS: "app.dev.internal.company.com:7283"

Why You Should Quote

  • Prevents shell expansion issues (* becomes literal instead of wildcard)
  • Avoids security vulnerabilities from unescaped values
  • Ensures consistent string interpretation across tools
  • Keeps YAML parsing happy , especially with values that look like numbers, booleans, or special characters

Where to Apply This

Quote your variables anywhere they’re defined:

  • .env files
  • values.yaml in Helm
  • docker-compose.yaml
  • Shell profiles (.bashrc, .zshrc)
  • GitHub Actions or CI/CD configs

Final Thoughts

These issues surfaced because of stricter parsing in updated tooling, but the underlying best practices have always applied. We should be handling environment values and output streams explicitly and consistently, not just where errors occur.

By quoting your variables and using proper file descriptors, you:

  • Future-proof your configs
  • Avoid subtle bugs
  • Improve readability for others (and future you)

Hope this helps anyone who are facing similar issues as us.. cheers

--

--

Prabesh
Prabesh

Written by Prabesh

Senior Site Reliability Engineer & Backend Engineer | Docker Captain 🐳 | https://www.linkedin.com/in/prabeshthapa

No responses yet