diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md
index 6440a01b39..6ea6128528 100644
--- a/doc/rule-descriptions.md
+++ b/doc/rule-descriptions.md
@@ -69,10 +69,11 @@
## WCAG 2.1 Level A & AA Rules
-| Rule ID | Description | Impact | Tags | Issue Type |
-| :----------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------- | :------ | :-------------------------------- | :--------- |
-| [autocomplete-valid](https://dequeuniversity.com/rules/axe/4.1/autocomplete-valid?application=RuleDescription) | Ensure the autocomplete attribute is correct and suitable for the form field | Serious | cat.forms, wcag21aa, wcag135 | failure |
-| [avoid-inline-spacing](https://dequeuniversity.com/rules/axe/4.1/avoid-inline-spacing?application=RuleDescription) | Ensure that text spacing set through style attributes can be adjusted with custom stylesheets | Serious | cat.structure, wcag21aa, wcag1412 | failure |
+| Rule ID | Description | Impact | Tags | Issue Type |
+| :----------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------- | :------ | :-------------------------------- | :------------------------- |
+| [empty-table-header](https://dequeuniversity.com/rules/axe/4.1/empty-table-header?application=RuleDescription) | Ensures table headers have discernible text | Minor | wcag131, cat.aria | failure, needs review |
+| [autocomplete-valid](https://dequeuniversity.com/rules/axe/4.1/autocomplete-valid?application=RuleDescription) | Ensure the autocomplete attribute is correct and suitable for the form field | Serious | cat.forms, wcag21aa, wcag135 | failure |
+| [avoid-inline-spacing](https://dequeuniversity.com/rules/axe/4.1/avoid-inline-spacing?application=RuleDescription) | Ensure that text spacing set through style attributes can be adjusted with custom stylesheets | Serious | cat.structure, wcag21aa, wcag1412 | failure |
## Best Practices Rules
diff --git a/lib/rules/empty-table-header.json b/lib/rules/empty-table-header.json
new file mode 100644
index 0000000000..9edb3cdc18
--- /dev/null
+++ b/lib/rules/empty-table-header.json
@@ -0,0 +1,13 @@
+{
+ "id": "empty-table-header",
+ "selector": "th, [role=\"rowheader\"], [role=\"columnheader\"]",
+ "tags": ["wcag131", "cat.aria"],
+ "reviewOnFail": true,
+ "metadata": {
+ "description": "Ensures table headers have discernible text",
+ "help": "Table header text must not be empty"
+ },
+ "all": [],
+ "any": ["has-visible-text"],
+ "none": []
+}
diff --git a/test/integration/rules/empty-table-header/empty-table-header.html b/test/integration/rules/empty-table-header/empty-table-header.html
new file mode 100644
index 0000000000..f8ab8feab9
--- /dev/null
+++ b/test/integration/rules/empty-table-header/empty-table-header.html
@@ -0,0 +1,49 @@
+
+
+ empty-table-header test
+
+
+
+
+
+
+
+
+
+ rowheader with name |
+
+
+
+
+
+ columnheader with name |
+
+
+
+
+
+
+
+
+
+
diff --git a/test/integration/rules/empty-table-header/empty-table-header.json b/test/integration/rules/empty-table-header/empty-table-header.json
new file mode 100644
index 0000000000..a1c725abc7
--- /dev/null
+++ b/test/integration/rules/empty-table-header/empty-table-header.json
@@ -0,0 +1,6 @@
+{
+ "description": "empty-table-header tests",
+ "rule": "empty-table-header",
+ "incomplete": [["#incomplete1"], ["#incomplete2"], ["#incomplete3"]],
+ "passes": [["#pass1"], ["#pass2"], ["#pass3"]]
+}