diff --git a/README.md b/README.md
index 97bcbf41b6..a3ded26aca 100644
--- a/README.md
+++ b/README.md
@@ -182,11 +182,12 @@ rules in templates can be disabled with eslint directives with mustache or html
### Best Practices
-| Name | Description | 💼 | 🔧 | 💡 |
-| :----------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :- | :- | :- |
-| [template-builtin-component-arguments](docs/rules/template-builtin-component-arguments.md) | disallow setting certain attributes on builtin components | | | |
-| [template-no-debugger](docs/rules/template-no-debugger.md) | disallow {{debugger}} in templates | | | |
-| [template-no-log](docs/rules/template-no-log.md) | disallow {{log}} in templates | | | |
+| Name | Description | 💼 | 🔧 | 💡 |
+| :------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :- | :- | :- |
+| [template-builtin-component-arguments](docs/rules/template-builtin-component-arguments.md) | disallow setting certain attributes on builtin components | | | |
+| [template-no-attribute-splat-on-html-element](docs/rules/template-no-attribute-splat-on-html-element.md) | disallow ...attributes on HTML elements | | | |
+| [template-no-debugger](docs/rules/template-no-debugger.md) | disallow {{debugger}} in templates | | | |
+| [template-no-log](docs/rules/template-no-log.md) | disallow {{log}} in templates | | | |
### Components
diff --git a/docs/rules/template-no-attribute-splat-on-html-element.md b/docs/rules/template-no-attribute-splat-on-html-element.md
new file mode 100644
index 0000000000..5b79d135f3
--- /dev/null
+++ b/docs/rules/template-no-attribute-splat-on-html-element.md
@@ -0,0 +1,43 @@
+# ember/template-no-attribute-splat-on-html-element
+
+
+
+Disallows using `...attributes` on HTML elements.
+
+## Rule Details
+
+The `...attributes` syntax should only be used on component elements, not on HTML elements, to avoid confusion and maintain clear component boundaries.
+
+## Examples
+
+Examples of **incorrect** code for this rule:
+
+```gjs
+
+
+
+```
+
+```gjs
+
+
+
+```
+
+Examples of **correct** code for this rule:
+
+```gjs
+
+
+
+```
+
+```gjs
+
+
+
+```
+
+## References
+
+- [eslint-plugin-ember no-attrs-in-components](https://github.com/eslint-plugin-ember/eslint-plugin-ember/blob/master/docs/rule/no-attrs-in-components.md)
diff --git a/lib/rules/template-no-attribute-splat-on-html-element.js b/lib/rules/template-no-attribute-splat-on-html-element.js
new file mode 100644
index 0000000000..11c8c9a580
--- /dev/null
+++ b/lib/rules/template-no-attribute-splat-on-html-element.js
@@ -0,0 +1,39 @@
+/** @type {import('eslint').Rule.RuleModule} */
+module.exports = {
+ meta: {
+ type: 'suggestion',
+ docs: {
+ description: 'disallow ...attributes on HTML elements',
+ category: 'Best Practices',
+ strictGjs: true,
+ strictGts: true,
+ url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-attribute-splat-on-html-element.md',
+ },
+ fixable: null,
+ schema: [],
+ messages: {
+ noAttributeSplat:
+ 'Do not use ...attributes on HTML elements. Use it only on component elements.',
+ },
+ },
+
+ create(context) {
+ return {
+ GlimmerElementNode(node) {
+ // Check if it's an HTML element (starts with lowercase letter)
+ if (node.tag && node.tag.length > 0 && node.tag[0] === node.tag[0].toLowerCase()) {
+ if (node.attributes) {
+ for (const attr of node.attributes) {
+ if (attr.name === '...attributes') {
+ context.report({
+ node: attr,
+ messageId: 'noAttributeSplat',
+ });
+ }
+ }
+ }
+ }
+ },
+ };
+ },
+};
diff --git a/tests/lib/rules/template-no-attribute-splat-on-html-element.js b/tests/lib/rules/template-no-attribute-splat-on-html-element.js
new file mode 100644
index 0000000000..9eba81d8ff
--- /dev/null
+++ b/tests/lib/rules/template-no-attribute-splat-on-html-element.js
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const rule = require('../../../lib/rules/template-no-attribute-splat-on-html-element');
+const RuleTester = require('eslint').RuleTester;
+
+//------------------------------------------------------------------------------
+// Tests
+//------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester({
+ parser: require.resolve('ember-eslint-parser'),
+ parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
+});
+
+ruleTester.run('template-no-attribute-splat-on-html-element', rule, {
+ valid: [
+ `
+
+ `,
+ `
+
+ `,
+ `
+
+ `,
+ ],
+
+ invalid: [
+ {
+ code: `
+
+ `,
+ output: null,
+ errors: [
+ {
+ message: 'Do not use ...attributes on HTML elements. Use it only on component elements.',
+ type: 'GlimmerAttrNode',
+ },
+ ],
+ },
+ {
+ code: `
+
+ `,
+ output: null,
+ errors: [
+ {
+ message: 'Do not use ...attributes on HTML elements. Use it only on component elements.',
+ type: 'GlimmerAttrNode',
+ },
+ ],
+ },
+ {
+ code: `
+
+ `,
+ output: null,
+ errors: [
+ {
+ message: 'Do not use ...attributes on HTML elements. Use it only on component elements.',
+ type: 'GlimmerAttrNode',
+ },
+ ],
+ },
+ ],
+});