YAML has exactly one comment character: the hash symbol. Every other question about YAML comments — how to span multiple lines, where the hash is forbidden, why your inline comment truncated a value, whether parsers preserve comments — traces back to understanding that single rule and the edges around it. This guide covers all of it, from the basic syntax to production workflows for stripping and validating commented YAML files.
YAML comment syntax basics
In YAML, a comment begins with a `#` character and extends to the end of the line. Everything from `#` onward — on that line only — is ignored by the parser. There are no closing delimiters, no block comment syntax, and no way to embed a comment in the middle of a value. One character, one rule, no exceptions.
The comment character and required whitespace
The YAML specification has one important nuance that trips up many developers: an inline comment must be preceded by at least one whitespace character. A `#` attached directly to a non-whitespace character is not treated as a comment — it is parsed as part of the surrounding scalar value. This matters most when adding comments after values on the same line.
- Correct inline comment: `timeout: 30 # seconds` — space before `#` is present
- Incorrect inline comment: `timeout: 30# seconds` — no space, `#` becomes part of the value
- Standalone comment line: `# This whole line is a comment` — no value before it
- Indented comment: ` # Indented comment inside a block` — indentation is fine
Warning
Comment syntax at a glance
Here are the three valid comment placement patterns in YAML. Every other variation is either identical to one of these or invalid:
- Start-of-line comment: `# comment text` — placed at column 0 or after leading spaces
- Inline comment after a scalar: `key: value # comment` — one or more spaces before `#`
- Inline comment after a list item: `- item # comment` — same space rule applies
Where comments are allowed
Comments are legal in the vast majority of places in a YAML document. Understanding the handful of locations where they are not helps you avoid confusing parse errors that don't mention comments at all.
Allowed positions
- Before any key-value pair: place documentation comments above the key on a dedicated line
- After any scalar value on the same line: `retries: 3 # max attempts`
- After a list item: `- production # primary environment`
- After a mapping key (no value yet): `database: # configured below`
- On blank lines between blocks: use comment lines freely as visual separators
- At the top of the file: file-level documentation comments are common in Kubernetes and CI/CD configs
The document start and end markers
Comments are also valid before and after the YAML document markers `---` (document start) and `...` (document end). This makes it possible to add file-level metadata comments before the document body in multi-document YAML streams.
| Location | Example | Comment allowed? |
|---|---|---|
| Standalone line | # Full-line comment | ✓ Yes |
| After scalar value | key: value # note | ✓ Yes (space required) |
| After list item | - item # note | ✓ Yes (space required) |
| Before document start | # Header --- | ✓ Yes |
| Inside a quoted string | "Say # hello" | ✗ No — # is literal |
| Inside a block scalar | |\n line # note | ✗ No — # is literal |
| Inside a flow sequence | [a, b # note, c] | ✗ No — syntax error |
| Inside a flow mapping | {a: 1 # note, b: 2} | ✗ Unreliable |
Note
Multi-line and block comments
YAML does not have a block comment syntax. There is no `/* ... */` equivalent, no `#!` heredoc, and no way to open a comment on one line and close it on another. To comment out multiple consecutive lines, you must prefix each line individually with `#`.
A comment is a hash character followed by characters that do not include line breaks, and up to — but not including — the next line break. A comment is treated as white space.
The conventional block comment pattern
Consecutive `#` lines are visually interpreted as a block comment, even though each line is technically an independent single-line comment. This is the universal convention in YAML files across all ecosystems — Kubernetes, GitHub Actions, Docker Compose, Helm charts, and CI/CD pipelines all use this pattern:
- `# ─────────────────────────────────────────`
- `# Database configuration`
- `# Update connection strings before deploying`
- `# ─────────────────────────────────────────`
Editor shortcuts for multi-line commenting
Every major code editor supports toggling comments across multiple selected lines in YAML files. Select the lines you want to comment out, then use the toggle shortcut — the editor adds or removes `#` from the start of each selected line simultaneously. This makes multi-line commenting as fast in YAML as it is in any other language.
- VS Code: Ctrl+/ (Windows/Linux) or Cmd+/ (macOS) — toggles # on selected lines
- JetBrains IDEs (IntelliJ, PyCharm, GoLand): Ctrl+/ or Cmd+/ — same behaviour
- Vim/Neovim: visual block mode (Ctrl+V), select lines, I, type #, Esc
- Emacs: M-; or comment-region with a YAML mode installed
- Sublime Text / TextMate: Ctrl+/ or Cmd+/ — toggles # on all selected lines
Tip
Where comments break things
Comments are safe in most YAML contexts, but there are four specific situations where a misplaced `#` will either produce a silent data error or a hard parse failure. Knowing these in advance prevents hours of confused debugging.
Inside quoted strings
A `#` inside a single-quoted or double-quoted string is always a literal character, never a comment. `message: "Hello # world"` stores the string `Hello # world`. This is correct and intentional. The problem arises with unquoted strings: `message: Hello # world` stores `Hello` and treats `# world` as a comment — silently truncating your value. Quote any unquoted string value that legitimately contains a `#`.
Inside block scalars (literal | and folded >)
Inside block scalar content — the indented lines that follow a `|` or `>` indicator — the `#` character has no special meaning. It is treated as a literal character and included in the string. You cannot comment out lines inside a block scalar. If you need to exclude content, you must remove it entirely rather than commenting it out.
Inside flow collections ([ ] and { })
Flow sequences and flow mappings are written on a single line. Placing a hash inside a flow collection is either a syntax error or produces an unexpected parse result depending on the parser. If you need to annotate individual items in a flow collection, convert it to block style (one item per line) where inline comments work correctly.
Bare # without a preceding space
As covered in the basics section, a `#` that is not preceded by whitespace is not recognised as a comment by spec-compliant parsers. The value `port: 8080#dev` is parsed as the string `8080#dev`, not the integer `8080` with a comment. Always write `port: 8080 # dev` with the space.
Warning
Stripping comments for production
Developer-facing YAML files are often heavily commented for documentation purposes. Those same files may need to be passed to APIs, deployment tools, or configuration management systems that either reject comments or add unnecessary parsing overhead. Stripping comments before transmission is the clean solution.
When you need to strip comments
- API endpoints that reject commented YAML — some REST APIs parse YAML request bodies and throw on comments
- Config serialisation round-trips — loading and re-dumping YAML with standard parsers silently strips comments
- Diff noise reduction — when reviewing config changes, stripped YAML diffs focus on actual value changes
- File size optimisation — heavily commented Kubernetes manifests can be meaningfully smaller without comments
- Automated processing pipelines — scripts that transform YAML often need clean input without comment-handling logic
YAML Comment Remover
Paste any YAML document and strip all comments instantly — clean output ready to copy, download, or pass to an API. Runs entirely in your browser with no uploads.
What comment stripping does and does not change
A correct comment stripping tool removes only the comment text — the `#` and everything after it on that line — without altering any values, keys, indentation, or structure. Standalone comment lines are replaced with blank lines or removed entirely. The resulting YAML parses identically to the original for all data values.
Note
Stripping via code (Python and Node.js)
If you need to strip comments programmatically as part of a pipeline, the simplest approach in any standard YAML library is a load-then-dump round-trip: parse the YAML into a data structure and immediately serialise it back. Comments are discarded on load and never written on dump. The output is valid YAML with identical data but no comments. For Python, `PyYAML` handles this in two lines. For Node.js, `js-yaml` does the same.
Real-world YAML comment patterns
Well-commented YAML files follow consistent patterns that make them easier to maintain, review, and hand off to other team members. These patterns appear across Kubernetes manifests, GitHub Actions workflows, Docker Compose files, and Helm chart values files.
File-header comments
Place a block of comments at the very top of the file to document its purpose, owner, and any critical context that is not obvious from the content alone. This is standard practice in Kubernetes manifests and Ansible playbooks. The comment block typically includes the file's purpose, the last modified date, and a link to related documentation or tickets.
Section separator comments
Long YAML files — particularly `docker-compose.yml` and Helm `values.yaml` files with dozens of top-level keys — benefit from visual section separators that help readers navigate. A line of `# ───────────────────────────────────────────────` or `# === DATABASE CONFIG ===` before a logical group of keys is a widely adopted convention. Use the YAML Anchors and Aliases Validator to check that your anchors and aliases are correct when restructuring heavily commented files.
Inline documentation for non-obvious values
Inline comments are most valuable for values that are not self-explanatory — magic numbers, environment-specific overrides, values in non-obvious units, or fields with interdependencies. A comment like `timeout: 300 # seconds; must match nginx keepalive_timeout` is far more useful than just the value alone. When working with environment variable substitution in YAML configs, the YAML Env Substitution Preview Tool can help you verify how commented defaults interact with runtime overrides.
- Document units: `memory: 512 # MB — increase to 1024 for production`
- Flag interdependencies: `enabled: false # also disable in config/prod.yaml`
- Explain defaults: `workers: 4 # matches CPU core count on t3.medium`
- Warn about required changes: `host: localhost # CHANGE before deploying`
- Reference external docs: `algorithm: RS256 # see RFC 7518, section 3.3`
Tip
Validating commented YAML
Adding comments to a YAML file creates new opportunities for syntax errors that aren't immediately obvious — a `#` inside an unquoted string, a missing space before an inline comment, or an accidental comment inside a block scalar. Running a validator after editing a commented YAML file is fast insurance against these issues.
What the YAML Validator catches
The YAML Validator parses your document against the YAML 1.2 specification and reports any syntax errors with line and column numbers. It catches misplaced comments, indentation errors introduced while adding comment lines, duplicate keys, and invalid scalar formats. Paste your YAML directly — no file upload, no signup, and nothing leaves your browser.
YAML Validator
Validate any YAML document against the YAML 1.2 spec — catches comment-related syntax errors, indentation issues, and duplicate keys with precise line numbers.
Detecting duplicate keys in annotated files
When developers comment out a key-value pair and then add a replacement below it, duplicate keys are a common result. For example: commenting out `timeout: 30` and adding `timeout: 60` beneath it leaves the commented version inactive — but if the comment is accidentally removed or the file is processed by a tool that strips comments, the duplicate becomes active and the lower value silently wins (or errors, depending on the parser). The YAML Duplicate Key Detector catches these before they cause problems.
Converting between formats with comments intact
If you are converting JSON to YAML using the JSON to YAML Converter, note that the output will not contain comments — JSON has no comment syntax, so there are no comments to carry over. Any documentation comments you want in the YAML output must be added manually after conversion. Similarly, the YAML Merge Tool may affect comment placement in merged files depending on how the merge is performed.
Comparing YAML configs before and after edits
When reviewing changes to commented YAML configurations — particularly in pull requests — the Diff Highlighter for JSON/YAML Configs surfaces meaningful value changes separately from comment-only edits. This makes code review faster and reduces the risk of approving an accidental value change buried in a diff full of comment updates.
Key takeaways
- YAML uses a single comment character: `#`. Everything from `#` to the end of the line is a comment.
- Inline comments require a space before `#` — writing `value# comment` without the space is a syntax error or produces an unexpected value.
- YAML has no block comment syntax — comment out multiple lines by prefixing each with `#` individually.
- `#` inside quoted strings and block scalars is always a literal character, never a comment.
- Comments are invisible to parsers — they are discarded on load and cannot be read back by PyYAML, js-yaml, or any standard library.
- Use the YAML Comment Remover to strip comments before passing YAML to APIs or deployment tools.
- Always validate with the YAML Validator after adding inline comments to catch silent value-truncation bugs.