Skip to content

Markdown Table Not Rendering? 11 Causes and Fixes

By MarkdownTables.com editorial teamUpdated

On this page

Why a Markdown table doesn’t render: the checklist

Work through these in order. The first three cause most failures.

  1. The delimiter row is missing or malformed (it must be line 2, made of hyphens).
  2. The header and delimiter rows have different cell counts.
  3. The table is indented four or more spaces, or sits inside a list item.
  4. There's no blank line before the table (matters outside GitHub).
  5. A literal pipe in a cell, code span or link isn't escaped.
  6. A cell contains a real line break.
  7. The table is inside an HTML tag without blank lines around it.
  8. The app or parser doesn't support tables (core CommonMark, Slack, Discord).
  9. The site generator follows different rules (GitHub Pages uses kramdown).
  10. An AI-generated table came wrapped in a code fence or lost its delimiter row.
  11. Invisible characters or long dashes broke the structure.

Faster: paste the table into the Markdown table validator, which points at the line and the rule it breaks. The rules themselves are in the Markdown table syntax guide.

Match the symptom to the cause

What you see, what causes it, and the fix
What you seeLikely causeFix
Raw pipes in one paragraphMissing or mismatched delimiter row, or no blank line aboveCauses 1, 2 and 4
Table in a gray monospace boxIndented 4+ spaces, or inside a code fenceCause 3, cause 10
Extra column, cells shifted rightUnescaped | in a cell, code span or wikilinkCause 5
Row cut in half, rest as text belowLine break typed inside a cellCause 6
Raw pipes only inside <details> or <div>No blank line between tag and tableCause 7
Works on GitHub, not on your sitekramdown, Python-Markdown or Hugo rulesCause 9
<br> shows as text, or the build failsHTML stripped (Hugo, Reddit) or MDX needs <br />Cause 9
Table renders but has no linesTheme CSS, not syntaxBorders
Never renders in a chat appNo table supportCause 8

The 11 causes in detail, with fixes

1. The delimiter row is missing or malformed

Symptom: all the lines run together as one paragraph with visible pipes. Cause: the second line must be a delimiter row: one cell per column, each made of hyphens with optional colons. The GFM spec accepts a single hyphen per cell; GitHub Docs recommend three. Equals signs (===), underscores, or a blank line between header and delimiter don't count.

❌ Broken: no delimiter row
Markdown
| Name | Role     |
| Ada  | Engineer |
| Alan | Analyst  |
Preview

Renders as plain text:

| Name | Role | | Ada | Engineer | | Alan | Analyst |

✅ Fixed: delimiter row on line 2
Markdown
| Name | Role     |
| ---- | -------- |
| Ada  | Engineer |
| Alan | Analyst  |
Preview
NameRole
AdaEngineer
AlanAnalyst

2. Header and delimiter cell counts differ

Symptom: raw pipes, even though a delimiter row is there. Cause: the header and delimiter rows must have exactly the same number of cells. Data rows are looser: in GFM, missing cells render empty and extra cells are silently dropped, so a short or long data row loses or misplaces data instead of breaking the table.

❌ Broken: three header cells, two delimiter cells
Markdown
| Name | Role | Team |
| ---- | ---- |
| Ada  | Engineer | Platform |
Preview

Renders as plain text:

| Name | Role | Team | | ---- | ---- | | Ada | Engineer | Platform |

✅ Fixed: one delimiter cell per header cell
Markdown
| Name | Role     | Team     |
| ---- | -------- | -------- |
| Ada  | Engineer | Platform |
Preview
NameRoleTeam
AdaEngineerPlatform

The table formatter pads every row to the header's width and lines up the pipes, which makes count mismatches easy to see.

3. The table is indented or inside a list

Symptom: the table appears as monospace text in a code box. Cause: four or more leading spaces (or a tab) make an indented code block. Fix: remove the indentation. Inside a list item, a table works when it is indented to the item's text column (three spaces after 1., two after -) and separated by blank lines; indent it further and it becomes code again.

❌ Broken: indented four spaces
Markdown
    | Name | Role     |
    | ---- | -------- |
    | Ada  | Engineer |
Preview

Renders as a code block:

| Name | Role | | ---- | -------- | | Ada | Engineer |

Fixed: a table inside a numbered listMarkdown
1. Set the environment variables:

   | Variable | Default |
   | -------- | ------- |
   | `PORT`   | `3000`  |

2. Start the server.

Inside a block quote or an Obsidian callout, start every table line with >, including the delimiter row.

4. No blank line before the table

Symptom: renders on GitHub but shows as text on your site or in another editor. Cause: GitHub and VS Code let a table start right after a line of text, but kramdown (Jekyll), Python-Markdown (MkDocs) and several editors need a blank line, and markdownlint reports it as MD058. Fix: blank lines before and after every table.

❌ Fragile: table directly under a paragraph
Markdown
Our pricing:
| Plan | Price |
| ---- | ----: |
| Pro  |   $12 |
Preview

On kramdown, Python-Markdown and others:

Our pricing: | Plan | Price | | ---- | ----: | | Pro | $12 |

✅ Fixed: blank line above the table
Markdown
Our pricing:

| Plan | Price |
| ---- | ----: |
| Pro  |   $12 |
Preview
PlanPrice
Pro$12

5. A pipe in a cell isn’t escaped

Symptom: an extra column appears and values shift right. Cause: every unescaped | starts a new cell, including pipes inside backticks, because GFM splits the row before it reads code spans. Shell commands, regexes, TypeScript union types and Obsidian wikilink aliases are the usual culprits. Fix: write \|. See escaping pipes for code spans and HTML entities.

❌ Broken: pipes inside a code span
Markdown
| Operator | Meaning    |
| -------- | ---------- |
| `a || b` | Logical OR |
Preview

The row splits into four cells; the last two are dropped:

Operator: `a · Meaning: (empty) Dropped: b` and Logical OR

✅ Fixed: each pipe escaped as \|
Markdown
| Operator   | Meaning    |
| ---------- | ---------- |
| `a \|\| b` | Logical OR |
Preview
OperatorMeaning
a || bLogical OR

6. A line break inside a cell

Symptom: a row ends early and the rest of the cell appears as text under the table. Cause: each line is a row, so pressing Enter inside a cell ends it. Fix: use <br> where the renderer allows HTML. See line breaks in tables.

❌ Broken: Enter pressed inside a cell
Markdown
| Step | Details          |
| ---- | ---------------- |
| 1    | Clone the repo
and install          |
Preview

The cell is split across two rows:

Row 1: 1 · Clone the repo Row 2: and install · (empty)

✅ Fixed: <br> inside the cell
Markdown
| Step | Details                         |
| ---- | ------------------------------- |
| 1    | Clone the repo<br>and install   |
Preview
StepDetails
1Clone the repo
and install

7. The table is inside an HTML block

Symptom: the table works on its own but not inside <details>, <div> or <center>. Cause: once a line starts an HTML block, Markdown isn't processed until a blank line ends it. Fix: leave a blank line after the opening tags and before the closing tag.

Broken: table touching the HTML tagsMarkdown
<details>
<summary>Supported versions</summary>
| Version | Status |
| ------- | ------ |
| 4.x     | Active |
</details>
Fixed: blank lines around the tableMarkdown
<details>
<summary>Supported versions</summary>

| Version | Status |
| ------- | ------ |
| 4.x     | Active |

</details>

8. The app doesn’t support tables

Symptom: a correct table never renders. Cause: tables aren't part of core CommonMark (spec 0.31.2); a parser has to enable a table extension (in markdown-it they're on by default, in remark you add remark-gfm, in Python-Markdown the tables extension). Chat apps are the other big group: Slack message formatting, Discord and Telegram don't draw tables. Jira and Confluence wiki markup use their own ||heading|| syntax (the Jira converter translates it).

Fix: enable the extension, or for chat apps use a code block or an image; see tables in Discord, Slack and Teams.

9. GitHub Pages, Hugo and other site generators

Static site generators don't use GitHub's renderer, so a table that works in a README can fail on the site:

  • GitHub Pages / Jekyll converts Markdown with kramdown. Leave a blank line before the table and start each row with |. Liquid runs first, so {{ }} in a cell is treated as a template tag.
  • Hugo (Goldmark) renders tables but replaces raw HTML such as <br> with a “raw HTML omitted” comment unless you allow it:
hugo.tomlTOML
# hugo.toml: allow raw HTML such as <br> in Markdown
[markup.goldmark.renderer]
  unsafe = true
  • Docusaurus and other MDX sites parse cells as JSX, so <br> must be written <br />, and a stray { or < in a cell can fail the build. Escape them or put them in code spans.
  • MkDocs (Python-Markdown) renders tables with its tables extension, but only when a blank line separates the table from the text above.

10. Tables pasted from ChatGPT or other AI tools

Tables from ChatGPT, Claude, Gemini or Copilot are usually valid Markdown, but copying them introduces predictable faults:

  • Wrapped in a code fence. If the answer showed the table as code, the copy includes ```markdown and ``` lines, and everything between them stays code. Delete those two lines.
  • Copied as rendered text. Selecting the rendered table copies tab- or space-separated text, not pipes. Use the response's copy button, or paste the text into the text-to-table converter.
  • Missing delimiter row or ragged rows in long generated tables, and leading spaces added by the paste. The table cleaner trims and normalizes them.
A table that will show as code: remove the first and last lineMarkdown
```markdown
| Model | Context |
| ----- | ------- |
| A     | 128k    |
```

11. Invisible characters and smart dashes

Word processors, chat apps and some websites swap hyphens for en or em dashes (–, —) and add non-breaking or zero-width spaces. The table looks right but the delimiter row is no longer made of hyphens. Retype the delimiter row, or let the validator flag hidden characters.

❌ Broken: em dashes instead of hyphens
Markdown
| Item | Qty |
| —— | —— |
| Pens | 4 |
Preview

Renders as plain text:

| Item | Qty | | —— | —— | | Pens | 4 |

✅ Fixed: plain hyphens
Markdown
| Item | Qty |
| ---- | --: |
| Pens |   4 |
Preview
ItemQty
Pens4

Markdown table not working in Obsidian

Obsidian renders standard pipe tables. When one doesn't render, check these Obsidian-specific causes first:

  • Pipes in wikilinks and embeds. An alias ([[Note|Alias]]) or an image size (![[photo.png|200]]) contains a pipe that splits the cell. Escape it: [[Note\|Alias]].
  • Source mode. Source mode always shows raw Markdown. Switch to Live Preview or Reading view.
  • Text directly above the table. Add a blank line between a paragraph and the table.
  • Callouts and quotes. Every line, including the delimiter row, needs the leading >.
  • Plugins and themes. If a valid table still fails, test in the Sandbox vault or with community plugins turned off; table-related plugins and CSS snippets can change how tables display.
❌ Broken: wikilink alias splits the cell
Markdown
| Note | Link |
| ---- | ---- |
| Plan | [[Roadmap|Q3 plan]] |
Preview

The alias spills into a third cell, which is dropped:

Plan | [[Roadmap

✅ Fixed: escaped pipe in the alias
Markdown
| Note | Link |
| ---- | ---- |
| Plan | [[Roadmap\|Q3 plan]] |
Preview
NoteLink
Plan[[Roadmap|Q3 plan]]

Obsidian shows the link as “Q3 plan”. Our preview shows the raw wikilink because wikilinks are Obsidian-only.

Open in editor : ✅ Fixed: escaped pipe in the alias

More on tables in Obsidian, including editing and plugins, in the Obsidian and Notion tables guide.

Table renders but borders or lines don’t show

If the table has rows and columns but no grid lines, the Markdown is fine. Markdown only produces an HTML <table>; borders, padding and stripes come from CSS. GitHub, GitLab and VS Code ship table styles, but many site themes, HTML exports, email clients and minimal Obsidian themes don't. Adding more dashes or pipes won't help. Add a style rule wherever you control the CSS (site stylesheet, Obsidian CSS snippet, Pandoc template):

GitHub-like table bordersCSS
table {
  border-collapse: collapse;
}
th,
td {
  border: 1px solid #d0d7de;
  padding: 6px 12px;
}
thead th {
  background: #f6f8fa;
}

You can't restyle tables on GitHub or GitLab, which strip style attributes. If you need a styled table for a slide or a message, the table to image tool renders one with borders.

Editor previews: VS Code, Typora, Notepad++

  • VS Code: the built-in preview (Ctrl/Cmd+Shift+V) renders GFM tables with markdown-it. If a table works there but not elsewhere, it's usually the blank-line rule. See the VS Code tables guide.
  • Typora renders tables as you type. If a pasted table stays as text, switch to Source Code mode, fix the delimiter row or blank line, and switch back.
  • Notepad++ has no Markdown renderer of its own. Preview plugins each bundle a parser, and if that parser doesn't enable tables, you'll see pipes however correct the syntax is. Check the table in another preview before rewriting it.
  • Jupyter renders tables in Markdown cells once the cell is run (Shift+Enter); in edit mode you see the source.

Which platforms render Markdown tables

Pipe-table and HTML line-break support by platform
PlatformPipe tablesHTML `<br>` in cells
GitHubA table may follow a line of text directly.YesYes
GitLabYesYes
ObsidianEscape | in wikilink aliases and image sizes.YesYes
NotionPasted Markdown is converted to a Notion table.Partly: On pasteNo
VS Code previewYesYes
JupyterYesYes
Pandoc / QuartoYes: Pipe and grid tablesPartly: HTML output only
Jekyll / GitHub Pages (kramdown)Blank line before the table; start rows with |.YesYes
MkDocsPython-Markdown tables extension, on by default.Yes: Blank line beforeYes
Docusaurus (MDX)YesPartly: Write <br />
Hugo (Goldmark)YesPartly: Needs unsafe = true
RedditUse the Markdown editor.YesNo
Slack and Discord messagesTyped tables stay as text. Slack apps can send a Block Kit table.NoNot applicable
Core CommonMark parsersTables are an extension, not part of CommonMark 0.31.2.No: Enable a GFM/table extensionNot applicable

✅ supported · ⚠️ partly or with a workaround · ❌ not supported · Last verified October 2026

Defaults shown; site generators can be configured differently.

Frequently asked questions

Why is my Markdown table not working in Obsidian?

Usually one of three things: a wikilink alias or image size inside the table ([[Note|Alias]], ![[img.png|200]]) whose pipe splits the cell, so escape it as \|; no blank line between the table and the text above it; or you are in Source mode, which always shows raw Markdown. Switch to Live Preview or Reading view.

Why are my Markdown table borders or lines not showing?

Borders are CSS, not Markdown. The syntax only produces an HTML <table>; the site theme, app theme or export stylesheet decides whether cells get lines. Add CSS such as th, td { border: 1px solid #ccc; }, or an Obsidian CSS snippet. On GitHub you can’t change it.

Why is my Markdown table not rendering on GitHub?

Check that the second line is a delimiter row with exactly as many cells as the header, that the table isn’t indented four or more spaces, that every literal | is escaped, and that any wrapping HTML tag has blank lines around the table. GitHub doesn’t need a blank line before a table, but other renderers do.

Does a Markdown table need a blank line before it?

Not on GitHub or in VS Code, but kramdown (Jekyll, GitHub Pages), Python-Markdown (MkDocs) and some editors do, and markdownlint flags it as MD058. Always leave a blank line before and after a table.

Why does my table show up as a code block?

It is indented four or more spaces (or a tab), or it is inside a triple-backtick code fence. Remove the indentation, or, inside a list item, indent it only to the item’s text column. AI tools often wrap tables in a fence labeled markdown; delete the two fence lines.

Why does a table from ChatGPT not render when I paste it?

Common reasons: the table came wrapped in a code fence, the delimiter row is missing or uses long dashes (—) instead of hyphens, or the paste added leading spaces. Copy with the response’s copy button to get Markdown, then run it through the table validator.

Why does my table render in VS Code but not on my site?

They use different parsers. VS Code uses markdown-it, which accepts a table right after a paragraph; Jekyll uses kramdown, MkDocs uses Python-Markdown, and Hugo strips raw HTML such as <br> by default. A blank line before the table and consistent cell counts fix most differences.

How do I find which line breaks my Markdown table?

Paste the table into the Markdown table validator. It reports a missing or mismatched delimiter row, rows with too many or too few cells, unescaped pipes, a missing blank line and hidden characters, each with its line number.

Find the broken line in seconds

The validator checks the delimiter row, cell counts, pipes, blank lines and hidden characters, with line numbers.

Validate a table