Skip to main content
HTML Validation

“td” start tag in table body.

About This HTML Issue

The HTML specification defines a strict content model for tables. The <td> (table data) element represents a single cell containing data, and it can only appear as a child of a <tr> element. Table sectioning elements like <tbody>, <thead>, and <tfoot> may only contain <tr> elements as direct children — not <td> or <th> cells directly. When the validator encounters a <td> start tag inside a table body (or other section) without a wrapping <tr>, it reports this error.

This issue typically arises in a few common scenarios:

  • A missing <tr> wrapper — the developer placed cells directly inside <tbody> or <table> without creating a row.
  • A prematurely closed <tr> — a typo or stray </tr> tag ended the row too early, leaving subsequent <td> elements orphaned.
  • Dynamically generated HTML — template engines or JavaScript may produce table markup where <tr> elements are accidentally omitted.

Why this matters

  • Standards compliance: The HTML living standard explicitly requires <td> elements to be children of <tr>. Violating this produces invalid markup.
  • Browser inconsistency: Browsers will attempt to error-correct by implicitly creating <tr> elements, but different browsers may interpret the malformed structure differently, leading to unpredictable rendering.
  • Accessibility: Screen readers and assistive technologies rely on correct table structure to navigate rows and columns. Missing <tr> elements can confuse these tools, making the data harder or impossible to understand for users who depend on them.
  • Maintainability: Invalid table markup is harder to style with CSS and harder for other developers to understand and maintain.

Examples

Incorrect — <td> directly inside <tbody>

The <td> elements are children of <tbody> instead of being wrapped in a <tr>:

<table>
  <tbody>
    <td>Name</td>
    <td>Age</td>
  </tbody>
</table>

Correct — <td> wrapped in <tr>

Adding a <tr> element creates a valid table row:

<table>
  <tbody>
    <tr>
      <td>Name</td>
      <td>Age</td>
    </tr>
  </tbody>
</table>

Incorrect — prematurely closed <tr> leaves orphaned cells

Here the first </tr> closes the row too early, so the second <td> ends up directly inside <tbody>:

<table>
  <tbody>
    <tr>
      <td>Cell 1</td>
    </tr>
      <td>Cell 2</td>
      <td>Cell 3</td>
  </tbody>
</table>

Correct — all cells placed inside proper rows

Either include all cells in one row, or create multiple rows as needed:

<table>
  <tbody>
    <tr>
      <td>Cell 1</td>
      <td>Cell 2</td>
      <td>Cell 3</td>
    </tr>
  </tbody>
</table>

Or, if you intended two separate rows:

<table>
  <tbody>
    <tr>
      <td>Cell 1</td>
    </tr>
    <tr>
      <td>Cell 2</td>
      <td>Cell 3</td>
    </tr>
  </tbody>
</table>

Incorrect — <td> directly inside <table> with no sections or rows

<table>
  <td>Alpha</td>
  <td>Beta</td>
</table>

Correct — minimal valid table structure

While <tbody> is optional (browsers add it implicitly), a <tr> is always required:

<table>
  <tr>
    <td>Alpha</td>
    <td>Beta</td>
  </tr>
</table>

To fix this error, inspect your table markup and ensure every <td> (and <th>) element is a direct child of a <tr>. Check for stray closing </tr> tags that might end rows prematurely, and verify that any dynamically generated table content produces <tr> wrappers around cell elements.

Find issues like this automatically

Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.

Help us improve our guides

Was this guide helpful?

Ready to validate your sites?
Start your free trial today.