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
Reddit 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:

  1. 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.

  2. Check for unclosed code blocks — an unterminated fenced code block (missing closing ) will cause everything after it to render as code. Search for lone in your document.

  3. 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.

  4. 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.

  5. Check your linter — use our Markdown Linter to catch structural issues (skipped heading levels, unclosed blocks, missing alt text) before they cause render failures.

  6. 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.