Why Your Markdown Isn't Rendering: A Troubleshooting Guide
You write clean Markdown, hit preview, and something goes wrong. The heading doesn’t appear. The code block is mangled. The table renders as pipe characters scattered across a paragraph. The bold text shows up as literal asterisks.
This isn’t a Markdown problem — it’s almost always a renderer problem. Markdown isn’t one thing; it’s a family of related syntaxes interpreted differently by dozens of parsers. The same document can render perfectly in VS Code, break in Confluence, and look different again on GitHub. Knowing which renderer you’re debugging is the key to solving the problem fast.
This guide covers the most common causes, organized by symptom and by platform.
Start Here: Identify Your Renderer
Before anything else, answer this question: what is rendering your Markdown?
| Where you’re writing | Renderer |
|---|---|
| GitHub README / PR description | GitHub Flavored Markdown (GFM) |
| Jekyll site | kramdown (usually) |
| Hugo site | Goldmark |
| Docusaurus / MDX | remark |
| VS Code preview | Markdown-it |
| Confluence | Not really Markdown — XHTML-based |
| Slack | mrkdwn (Slack’s own format) |
| Obsidian | Markdown-it with plugins |
| Snoomark (new) or older Reddit Markdown | |
| Notion | Notion’s own parser (paste-only) |
Each renderer supports a different subset of Markdown features. Most support CommonMark as a baseline; the extended features (tables, task lists, footnotes, strikethrough) vary.
The Most Common Causes
1. The renderer doesn’t support that syntax
This is the most frequent cause. Something looks like standard Markdown but isn’t supported by your target renderer.
Examples:
- Footnotes — CommonMark doesn’t include them. They work in Pandoc, kramdown, and GitHub (for Wikis), but not in basic GFM for README files.
- Definition lists — supported by kramdown, not by most others.
- Custom heading IDs (
## Heading {#my-id}) — supported by Pandoc and some Hugo themes, not in GitHub Flavored Markdown. - Subscript/superscript (
H~2~O,x^2^) — Pandoc and some plugins only.
Fix: Check the renderer’s documentation for which extensions it supports. Don’t assume something works because it works in your local editor.
2. Missing blank lines around block elements
Markdown parsers are pickier than you’d expect about blank lines. Most renderers require a blank line before and after:
- Block-level HTML tags
- Fenced code blocks
- Lists that follow a paragraph
- Headings that follow content
Without the blank line, a renderer may treat the content as a paragraph continuation instead of a new block.
This won’t render correctly:
Some text.
```code
example
More text.
**This will:**
```markdown
Some text.
```code
example
More text.
### 3. Indentation inconsistency in lists
List item continuation and nested lists depend on consistent indentation. The rules vary by renderer:
- CommonMark requires **2 spaces** of indentation for nested items
- Some older parsers require **4 spaces** or a tab
- Mixing tabs and spaces causes unpredictable behaviour
**Symptom:** A nested list renders flat, or a code block inside a list item renders as a paragraph.
**Fix:** Use consistent 2-space indentation throughout, and never mix tabs with spaces.
### 4. HTML inside Markdown getting stripped
Many renderers strip raw HTML for security reasons. This is intentional.
- **GitHub** strips `<style>`, `<script>`, and most event handlers from README files. It keeps safe tags like `<details>`, `<summary>`, `<kbd>`, and `<br>`.
- **Hugo's Goldmark** strips raw HTML by default. You must add `markup.goldmark.renderer.unsafe: true` to your config to allow it.
- **Confluence** rejects HTML entirely unless you use the dedicated HTML Macro.
- **Docusaurus/MDX** interprets HTML as JSX — missing a closing tag or a non-void self-closing tag will break the entire page.
**Symptom:** Your carefully crafted HTML layout renders as plain text, or throws an error.
**Fix:** Check your renderer's HTML-in-Markdown policy. For Hugo, enable unsafe rendering. For GitHub, use only the subset of HTML tags that GFM allows. For Confluence, use the HTML Macro.
### 5. Jekyll: Liquid syntax in code blocks
Jekyll processes Liquid template tags *before* Markdown rendering. This means any `{% ... %}` or `{{ ... }}` inside a code block — even a fenced one — will be executed as a template, not displayed as code.
**Symptom:** Code block content disappears, or you see a Liquid error like `Liquid Warning: Liquid syntax error`.
**Fix:** Wrap the problematic code block in `{% raw %}` and `{% endraw %}` tags. Your file should look like this:
```bash
echo "Hello {{ name }}"
This is required any time your code block contains {{, }}, {%, or %} — common when documenting Liquid, Jinja2, Handlebars, or Hugo templates.
6. Jekyll: Posts not appearing (date in the future)
Jekyll doesn’t render posts with a date in the future by default.
Symptom: A post exists in _posts/ but doesn’t appear on the site.
Fix: Either set the date to today or earlier in the frontmatter, or add future: true to _config.yml in your development environment. Don’t add it to production unless you intend posts to publish early.
7. Hugo: Shortcodes in Markdown code blocks
Hugo processes shortcodes ({{< ... >}}) before rendering, same as Jekyll’s Liquid problem.
Symptom: A code block showing how to use a Hugo shortcode is broken or missing.
Fix: Use Hugo’s {{</* ... */>}} comment syntax inside shortcode examples, or wrap in a highlight shortcode instead of a fenced block:
{{</* warning */>}}
This is a warning box.
{{</* /warning */>}}
8. Tables: Missing separator row
A Markdown table requires a separator row of dashes between the header and the body rows. Without it, most renderers won’t recognise it as a table at all.
This won’t render as a table:
| Name | Role |
| Alice | Admin |
| Bob | Editor |
This will:
| Name | Role |
|------|------|
| Alice | Admin |
| Bob | Editor |
The number of dashes doesn’t matter (minimum 1 per cell), but the separator row is required.
9. Confluence: Markdown paste doesn’t work as expected
Confluence is not a Markdown-native tool. Its internal format is XHTML. When you paste Markdown, Confluence converts it — and the conversion is lossy.
What works on paste:
- Basic headings, bold, italic
- Simple unordered and ordered lists
- Code blocks (language tag is often dropped)
What breaks:
- Tables (often rendered as plain text)
- Task lists
- Footnotes
- Nested blockquotes
- Raw HTML
Better approach: Use the /markdown slash command (Confluence Cloud) or the Wiki Markup import path. For reliable table conversion, use our Markdown to Confluence tool to convert to wiki markup first, then paste using Insert → Wiki Markup.
See our full guide: Markdown in Confluence: What Actually Works.
10. GitHub: GFM vs standard Markdown
GitHub Flavored Markdown adds extensions on top of CommonMark, but it also restricts some things.
Things that work in GFM but not standard Markdown:
- Tables (pipe syntax)
- Task lists (
- [x]) - Strikethrough (
~~text~~) - Autolinks (
https://...without brackets) - Alerts / callouts (
> [!NOTE])
Things that do NOT work in GitHub README files:
- Footnotes (they work in GitHub Wikis and GitHub Pages, but not README.md)
- Definition lists
- Custom CSS or
<style>tags <script>tags
Symptom: A footnote [^1] renders as literal text in a README but works fine in your local Markdown editor.
Fix: Check the GitHub Flavored Markdown spec for what’s in-scope. For README files specifically, if a feature isn’t listed there, it won’t work.
Platform Comparison: What Renders Where
| Feature | GitHub README | Jekyll (kramdown) | Hugo (Goldmark) | Obsidian | Confluence |
|---|---|---|---|---|---|
| Tables | ✅ | ✅ | ✅ | ✅ | ⚠️ partial |
| Task lists | ✅ | ✅ plugin | ✅ | ✅ | ❌ |
| Footnotes | ❌ | ✅ | ✅ | ✅ | ❌ |
| Strikethrough | ✅ | ✅ | ✅ | ✅ | ⚠️ |
| Definition lists | ❌ | ✅ | ❌ | ❌ | ❌ |
| Raw HTML | ⚠️ safe subset | ✅ | ⚠️ opt-in | ⚠️ | ❌ |
| Math (LaTeX) | ✅ (2022+) | ✅ plugin | ✅ plugin | ✅ | ❌ |
| Mermaid diagrams | ✅ | ✅ plugin | ✅ plugin | ✅ | ❌ |
| Custom heading IDs | ❌ | ✅ | ✅ | ✅ | ❌ |
See our full platform compatibility guide for a more detailed breakdown.
Debugging Workflow
When your Markdown breaks, work through this checklist:
-
Isolate the problem — create a minimal reproduction. Copy just the broken section into a fresh file. If that renders correctly, the issue might be something earlier in the document (unclosed code block, broken table, etc.) affecting parsing.
-
Check for unclosed code blocks — an unterminated fenced code block (missing closing
) will cause everything after it to render as code. Search for lonein your document. -
Check the raw output — inspect the HTML source of the rendered page (right-click → View Source). This tells you whether the renderer is producing output at all or silently failing.
-
Test in a known-good renderer — paste the Markdown into our live editor to see if it renders there. If it does, the issue is your target renderer, not the Markdown itself.
-
Check your linter — use our Markdown Linter to catch structural issues (skipped heading levels, unclosed blocks, missing alt text) before they cause render failures.
-
Read the error logs — Jekyll and Hugo both print build warnings to the terminal. A Liquid error, a missing file, or a frontmatter parse failure will appear there before you spend 30 minutes debugging Markdown.
Summary
Most Markdown rendering failures fall into one of these categories:
- Renderer doesn’t support the syntax — check the spec for your specific tool
- Missing blank lines around block elements
- Template tags in code blocks — use
{% raw %}in Jekyll, comment syntax in Hugo - HTML being stripped — check security settings, use only allowed tags
- Confluence — it’s not a Markdown renderer; use our wiki markup converter
- Table missing separator row — always required
The fix is almost always straightforward once you know which renderer is involved. Start there, and the rest usually follows.
Related Posts and Tools
- Markdown Across Platforms: What Works in GitHub, Notion, Obsidian, and Confluence — the reference guide for cross-platform compatibility
- Markdown in Confluence: What Actually Works — deep dive on Confluence specifically
- Markdown for Technical Writers: The Docs-as-Code Workflow — setting up markdownlint and Vale in CI
- Markdown Linter — check your Markdown for style issues instantly
- Markdown Live Editor — test how your Markdown renders in real time
- Markdown to Confluence — convert Markdown to Confluence wiki markup