exceltomarkdown.com
Troubleshooting

Why Markdown Tables Break (and How to Fix Them)

Four symptoms, four causes, four fixes — diagnose any misbehaving table in under a minute.

Symptom 1 — The table renders as plain text

Cause: the separator row is missing, misspelled, or separated from the header by a blank line. Fix: place a dash row immediately under the header, with at least three dashes per column, e.g. |:---------|:---:|. Compare against thesyntax reference if it still fails.

Symptom 2 — One cell splits into extra columns

Cause: a literal pipe (|) inside cell content. Fix: escape every in-cell pipe as \|. This is the most common defect in hand-written tables — and the reason converter output escapes pipes automatically.

Symptom 3 — Rows have different column counts

Cause: ragged rows: a dropped empty field, or a quoted CSV value that split early during a manual conversion. Fix: count the header columns, then pad short rows with empty cells (| |) until every row matches. Re-running the source through theExcel converter or CSV converter fixes this class of error by construction.

Symptom 4 — A multiline cell collapses the table

Cause: a literal newline inside a row — renderers end the row there and everything below shifts. Fix: join the cell content onto one line with <br> tags where breaks belong.

The 30-second fix checklist

  1. Header row present, separator row directly beneath it.
  2. Every row has the same number of pipes.
  3. All in-cell pipes escaped as \|.
  4. No literal newlines inside rows — <br> instead.
  5. Blank line above the header and below the last row.

Symptom 5 — The table is trapped inside a gray code box

Cause: leading whitespace indentation. In standard Markdown specifications, any block of text preceded by 4 spaces or a single tab character is interpreted as an indented verbatim code block.

Fix: select the entire table in your code editor and press Shift + Tab to remove leading indentation. Ensure the starting pipe of the header row sits flush against column 0 of your document.

Symptom 6 — A blank line splits one table into two disjointed fragments

Cause: inserting an empty row to visually separate categories of data. In GFM parsing logic, an empty line immediately terminates the table state machine. Any data rows placed beneath that blank line lack a delimiter row, causing them to render as ugly unformatted plain text.

Fix: never insert empty lines inside a table. Instead, insert a section header row using bold text or em-dashes across all cells (e.g. | **Category B: Peripheral Hardware** | --- | --- |).

Symptom 7 — MathJax or LaTeX equations breaking column boundaries

Cause: embedding mathematical formulas containing absolute value bars or matrix notation (such as $|x| < 1$ or $\begin{vmatrix} a & b \end{vmatrix}$). Because the Markdown lexer executes before LaTeX rendering engines, the unescaped vertical bars are treated as table delimiters.

Fix: replace raw vertical bars in LaTeX with their corresponding commands: use \lvert x \rvert instead of |x|, or escape the pipe as $\|x\|$.

Automated Diagnostic Script in Node.js

If you maintain documentation with dozens of Markdown tables across large repositories, use this automated validation script in your CI pipeline to catch broken delimiters before code review:

// validate-tables.mjs
import fs from 'node:fs';

function validateMarkdownTables(content) {
  const lines = content.split('\n');
  let inTable = false;
  let expectedCols = 0;
  const errors = [];

  for (let i = 0; i < lines.length; i++) {
    const line = lines[i].trim();
    const isPipeRow = line.startsWith('|') && line.endsWith('|');

    if (!inTable && isPipeRow) {
      // Potential header
      const nextLine = (lines[i + 1] || '').trim();
      const isDelimiter = /^\|(?:\s*:?-+:?\s*\|)+$/.test(nextLine);
      if (isDelimiter) {
        inTable = true;
        expectedCols = line.split('|').length - 2;
        i++; // skip delimiter row
        continue;
      }
    } else if (inTable) {
      if (!isPipeRow) {
        inTable = false;
        continue;
      }
      const cells = line.split(/(?<!\\)\|/).length - 2;
      if (cells !== expectedCols) {
        errors.push('Line ' + (i + 1) + ': Expected ' + expectedCols + ' columns, found ' + cells);
      }
    }
  }
  return errors;
}

Running this regex-based token counter flags unescaped pipes and ragged column counts instantly across all your docs.

Symptom 8 — Invisible UTF-8 BOM Header Corrupting Delimiters

Cause: when CSV files are exported from legacy Windows software (like older Microsoft Excel editions), the file may start with an invisible three-byte sequence: 0xEF, 0xBB, 0xBF (the UTF-8 Byte Order Mark). When pasted into a Markdown document, these invisible zero-width bytes sit in front of the opening pipe of line 1, causing GFM parsers to reject the header row.

Fix: in VS Code, inspect the bottom status bar: if it reads UTF-8 with BOM, click it and selectSave with Encoding → UTF-8 (without BOM). Alternatively, re-paste the table through our online converter, which automatically strips zero-width non-breaking spaces and BOM markers during clipboard sanitization.

Symptom 9 — Mixed CRLF vs LF Line Endings in Git Pull Requests

Cause: team members collaborating across Windows and macOS/Linux workstations with misconfigured git core.autocrlf settings. If one developer adds rows with Windows carriage return line feeds (\r\n) to a file using Unix line feeds (\n), older Markdown processors may fail to recognize the row boundaries correctly.

Fix: normalize line endings in your repository by adding a .gitattributes file containing* text=auto eol=lf. Run git add --renormalize . to ensure uniform Unix line endings across all Markdown documentation.

VS Code Regex Search & Replace Formulas

Fix common table formatting errors across hundreds of files in seconds using regular expression find-and-replace:

Static Site Generator Compatibility: Hugo, Jekyll, & Docusaurus

If your table renders properly on GitHub but breaks inside your documentation portal:

Emergency Recovery: Re-Converting Damaged Tables in 3 Steps

If a legacy Markdown table has become so mangled by broken column counts and unescaped special characters that hand-editing line-by-line is impractical:

  1. Select & Copy the Raw Markdown: Copy the broken table text directly from your markdown document into your clipboard.
  2. Paste into ExcelToMarkdown: Open our converter workbench and paste the text into the input textarea. The lexer will isolate cell contents, strip zero-width BOM noise, and reconstruct a clean rectangular grid.
  3. Copy Clean Output: Click Copy Markdown to paste the newly repaired, perfectly padded GFM table back into your documentation.

Formatting Tables in Slack, Discord, & Microsoft Teams

Chat applications implement highly restricted Markdown variants that do not support GFM table syntax:

Related guides

Frequently asked questions

Why does my Markdown table show as plain text with visible pipes?

The separator row is missing or malformed. Add a row of dashes (with optional alignment colons) directly under the header — that row is what triggers table rendering.

Why did one cell split into two columns?

It contains an unescaped pipe character. Escape every literal | inside cell content as \| and the columns will line up again.

Why do some rows have more cells than others?

Ragged rows: an empty field was dropped or a quoted value split early. Pad short rows with empty cells so every row matches the header column count.