Why Is GitHub Markdown Not Rendering? 16 Causes & Fixes
Your README looked fine in your editor, then GitHub showed raw symbols, a collapsed table, or a missing image. This guide starts from what you see, explains why GitHub renders it that way, and gives a fix you can copy. Every parser-level example was tested against GitHub’s own Markdown parser.
Most broken READMEs come down to six things: a missing space after #, a table whose delimiter row doesn’t match the header, an unclosed ``` fence, text accidentally indented four spaces, Markdown written directly under an HTML block without a blank line, and image paths with the wrong folder or letter case.
Fastest way to find yours: paste the file into our GitHub Markdown Preview and look for the first place the rendering goes wrong, then match the symptom in the table below.
How GitHub turns Markdown into a page
Knowing the pipeline tells you where a problem comes from. According to GitHub’s markup documentation, a Markdown file goes through these steps:
- 1. Parse
The text is converted to HTML following the GFM spec. Headings, lists, tables, code fences, and indentation problems happen here.
- 2. Sanitize
Unsafe HTML is removed: scripts, styles, iframes, and style/class/id attributes. This is why some HTML "disappears".
- 3. Enhance
Filters add syntax highlighting, emoji, task lists, heading anchors, alerts, relative-link rewriting, and autolinks.
- 4. Render in the browser
Mermaid diagrams and math are drawn on github.com itself, which is why they never appear on raw file URLs.
Find your problem by symptom
| What you see on GitHub | Likely cause |
|---|---|
| A # or ## is visible at the start of a line | |
| Separate lines are merged into one | |
| Literal ** or _ characters around words | |
| Words in < > are missing | |
| A table is a paragraph full of | characters | |
| Nested bullets are flat, or numbering restarts | |
| Normal text is in a gray code box | |
| Broken image icon or 404 on a link | |
| A table-of-contents link does not jump | |
| [!NOTE] is visible in a plain quote | |
| Diagram source code instead of a diagram | |
| Raw LaTeX instead of formatted math | |
| [^1] is visible as text | |
| Whole file is plain text, or the README is cut off |
Headings, text & line breaks
Missing space after the # in a heading
What you see: A heading shows up as normal text with the # still visible.
Why: An ATX heading needs at least one space (or tab) between the # characters and the text. "#Installation" is just a paragraph that happens to start with a #. Up to three spaces before the # are allowed; four turn the line into a code block.
Line breaks disappear in .md files
What you see: Lines you typed one under another run together into a single line.
Why: In a .md file, a single newline inside a paragraph is a "soft break" and renders as a space. GitHub only turns single newlines into line breaks in issues, pull requests, and discussions — which is why the same text looks different in a comment and in a README.
Name: Ada Lovelace Role: Maintainer Timezone: UTC
Name: Ada Lovelace\ Role: Maintainer\ Timezone: UTC
Bold or italic shows literal * or _ characters
What you see: You see **asterisks** or _underscores_ around words instead of bold or italic text.
Why: Emphasis markers must touch the text they wrap: "** Important **" with spaces inside is not bold. Underscores are also ignored inside words on purpose (so snake_case_names stay intact), which means _ cannot italicize part of a word — use * for that.
** Important ** step This is un_believe_able
**Important** step This is un*believe*able
Text inside <angle brackets> vanishes
What you see: Words like List<String> or <your-token> are missing from the rendered page.
Why: Markdown passes HTML through, so <String> and <your-token> are read as HTML tags. GitHub's sanitizer then removes tags it does not allow, and the text inside the brackets disappears. A URL in angle brackets, like <https://example.com>, is an autolink and is fine.
Returns a List<String>. Set API_KEY=<your-token> in .env
Returns a `List<String>`. Set `API_KEY=<your-token>` in `.env` Or escape the bracket: List\<String>
Tables, lists & code blocks
Table renders as plain text or splits cells wrongly
What you see: You see a paragraph full of | characters, or a cell is cut in half.
Why: A GFM table needs a header row followed directly by a delimiter row (| --- | --- |) with exactly the same number of cells. A | inside a cell starts a new cell — even inside `backticks` — unless you escape it as \|. Extra cells in a row are silently dropped. GitHub Docs also asks for a blank line before the table and at least three hyphens per column; GitHub's parser is more forgiving in our tests, but other renderers are not, so follow the documented form.
| Flag | Meaning | | --- | | -a | all | | Pattern | Matches | | --- | --- | | `a|b` | a or b |
| Flag | Meaning | | --- | --- | | -a | all | | Pattern | Matches | | --- | --- | | `a\|b` | a or b |
Nested list items are not nested
What you see: Sub-items show up at the top level, or a numbered list restarts in the middle.
Why: A nested item — or any paragraph or code block that belongs to an item — must be indented at least to where the parent item's text starts: 2 spaces under "- item", 3 under "1. item", 4 under "10. item". With less indentation the line becomes a new, separate list.
1. Install the CLI - Requires Node 20 2. Run the setup
1. Install the CLI - Requires Node 20 2. Run the setup
Text indented 4 spaces turns into a code block
What you see: A normal paragraph appears in a gray, monospaced box.
Why: Four or more spaces (or a tab) at the start of a line outside a list create an indented code block, and Markdown inside it is shown literally. This often happens after pasting from an email, an IDE, or a template that was indented for readability.
Steps to reproduce:
Open the app and click **Save**.Steps to reproduce: Open the app and click **Save**.
Unclosed or mismatched code fence
What you see: Everything after a certain point is one giant code block.
Why: A fenced code block runs until a closing fence that uses the same character (` or ~) and at least as many of them. If the closing ``` is missing — or you open with ``` and close with ~~~ — the rest of the file becomes code. If the code itself contains ```, wrap it in a longer fence such as ````.
```bash npm install ## Usage Run `npm start`.
```bash npm install ``` ## Usage Run `npm start`.
Links, images & HTML
Broken images and relative links
What you see: Images show a broken icon or only their alt text; links to other files lead to a 404.
Why: GitHub resolves a relative path from the folder that contains the Markdown file, or from the repository root when the path starts with /. Paths in a Git repository are case-sensitive even if your laptop's file system is not, absolute paths from your computer (C:\ or file:///) never work, and the image must be committed and pushed.
<!-- in docs/guide.md -->  
<!-- in docs/guide.md -->    <!-- from the repo root -->
Links to a section (#anchor) go nowhere
What you see: Clicking a table-of-contents link does not scroll to the heading.
Why: GitHub builds each heading's anchor by lowercasing it, turning spaces into hyphens, and removing other punctuation and formatting. A repeated heading gets -1, -2, … appended. If your link differs in any character — or you later renamed the heading — the jump fails.
- [Getting Started](#Getting-Started) - [FAQ & Help](#faq-&-help) ## Getting Started ## FAQ & Help
- [Getting Started](#getting-started) - [FAQ & Help](#faq--help) ## Getting Started ## FAQ & Help
Markdown next to HTML is ignored (or your HTML is stripped)
What you see: Raw ## and ** characters appear right after an HTML tag, or your inline styles have no effect.
Why: A block-level tag such as <div> or <p> starts an HTML block that lasts until the next blank line, and Markdown is not processed inside it. Separately, GitHub sanitizes HTML: tags like <script>, <style>, and <iframe> are removed, along with style, class, and id attributes.
<div align="center"> <img src="logo.png" width="120"> </div> ## Getting Started **Install** first.
<div align="center"> <img src="logo.png" width="120"> </div> ## Getting Started **Install** first.
GitHub-only features
Alerts ([!NOTE], [!WARNING]) show as plain quotes
What you see: You see a gray quote with the [!NOTE] text still visible.
Why: An alert is a blockquote whose first line is exactly [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], or [!CAUTION]. Other words such as [!INFO] or [!DANGER], a missing exclamation mark, or text on the marker line do not create an alert. GitHub Docs also states that alerts cannot be nested inside other elements, such as list items.
> [!INFO] > INFO is not a supported type. > [NOTE] > The exclamation mark is missing.
> [!NOTE] > Useful information users should know. > [!WARNING] > Urgent information to avoid problems.
Mermaid diagrams show code or an error
What you see: You see the diagram's source text, a syntax-error box, or an empty space.
Why: GitHub only renders Mermaid inside a fenced code block whose language is exactly mermaid. A syntax error shows an error instead of the diagram, and brand-new Mermaid syntax works only after GitHub upgrades its Mermaid version. Diagrams render on github.com (files, issues, PRs, discussions, wikis) but not on raw.githubusercontent.com, and not on a GitHub Pages site unless that site loads Mermaid itself.
Math shows as raw LaTeX
What you see: Equations appear as plain text with backslashes, or dollar amounts break an equation.
Why: GitHub recognizes $...$ and $`...`$ for inline math, and $$...$$ or a ```math block for display math. The LaTeX delimiters \(...\) and \[...\] are not recognized. When a literal dollar sign shares a line with an equation, GitHub Docs says to wrap it as <span>$</span> (or escape it as \$ inside the math).
\(E = mc^2\) To split $100 in half, we calculate $100/2$
$`E = mc^2`$
```math
\sum_{i=1}^{n} x_i
```
To split <span>$</span>100 in half, we calculate $100/2$Footnotes show as [^1] text
What you see: The footnote marker stays as literal [^1] text, or footnotes are missing on a wiki page.
Why: Each reference like [^bench] needs a definition with the identical label, written as [^bench]: text on its own line. The definition can be anywhere — GitHub always moves footnotes to the bottom. Footnotes are not supported in GitHub wikis.
See the benchmarks[^bench]. [^benchmark]: Run on an M2 laptop.
See the benchmarks[^bench]. [^bench]: Run on an M2 laptop.
File-level problems
The file is not rendered, not shown, or cut off
What you see: The file shows as plain text, the repository page shows a different README, or the end of the README is missing.
Why: GitHub renders Markdown only for recognized extensions: .md, .markdown, .mdown, and .mkdn. When a repository has several READMEs, GitHub shows the one in .github first, then the root, then docs. Anything after the first 500 KiB of a README is truncated.
README.txt ← shown as plain text .github/README.md ← shown instead of ./README.md README.md (650 KiB) ← truncated after 500 KiB
README.md ← rendered as Markdown ./README.md only ← or keep the one you want in .github/ README.md under 500 KiB ← move long docs to docs/ or a wiki
Pre-push checklist
Run through this before pushing a README, or keep it next to your editor:
- Every heading has a space after the #
- Line breaks use a trailing \ or a blank line
- No spaces just inside ** or *
- Placeholders like <token> are in backticks
- Table delimiter row matches the header cell count
- Pipes inside table cells are escaped as \|
- Nested list items are indented to the parent text
- No stray 4-space indentation outside lists
- Every ``` fence has a matching closing fence
- Image paths are relative and match the file name's case
- Section links match the generated #anchor
- Blank line after every HTML block
- Alerts use one of the five [!TYPE] markers
- Mermaid blocks use the mermaid language tag
- Math uses $ / $$ / ```math, not \( \)
- Footnote labels match their definitions
Every example labeled Tested with cmark-gfm was run through cmark-gfm 0.29.0.gfm.13 — the reference implementation of the GitHub Flavored Markdown spec, maintained by GitHub — with tables, strikethrough, autolinks, task lists, and footnotes enabled. We confirmed that each “Broken” example produces the broken output described and each “Fixed” example renders correctly.
Behavior that happens after parsing — relative-path rewriting, HTML sanitizing, alerts, Mermaid, math, and README selection — cannot be reproduced with the parser alone, so those sections are checked against GitHub’s official documentation, linked in the sources below. Where GitHub’s docs are stricter than its parser (tables), we say so and recommend the documented form.
“Try it” links appear only where this site’s previewer reproduces GitHub’s behavior. Spotted something out of date? Email hello@markdownpreview.net.
Frequently asked questions
Does GitHub use standard Markdown or its own version?
Why does my text look different in a comment than in my README?
Why does my README look different in VS Code than on GitHub?
Which HTML can I use in a GitHub README?
How can I see exactly what GitHub will render before I merge?
My Markdown is correct but GitHub still shows the old version. Why?
Sources
- GitHub Docs — Basic writing and formatting syntax — headings, line breaks, anchors, relative links, lists, footnotes, alerts
- GitHub Docs — Organizing information with tables
- GitHub Docs — Creating and highlighting code blocks
- GitHub Docs — Creating diagrams
- GitHub Docs — Writing mathematical expressions
- GitHub Docs — About READMEs — README location order and the 500 KiB limit
- GitHub Flavored Markdown Spec — including the disallowed raw HTML (tag filter) extension
- github/markup — recognized file extensions and the sanitization step
- github/cmark-gfm — the parser we used to test every parser-level example