diff --git a/src/evented-tokenizer.ts b/src/evented-tokenizer.ts
index 80d0b4b..58b71de 100644
--- a/src/evented-tokenizer.ts
+++ b/src/evented-tokenizer.ts
@@ -267,17 +267,17 @@ export default class EventedTokenizer {
       let char = this.consume();
 
       if (isSpace(char)) {
-        this.transitionTo(TokenizerState.beforeAttributeName);
-        this.tagNameBuffer = '';
+        this.delegate.reportSyntaxError('closing tag must only contain tagname');
       } else if (char === '/') {
-        this.transitionTo(TokenizerState.selfClosingStartTag);
-        this.tagNameBuffer = '';
+        this.delegate.reportSyntaxError('closing tag cannot be self-closing');
       } else if (char === '>') {
         this.delegate.finishTag();
         this.transitionTo(TokenizerState.beforeData);
         this.tagNameBuffer = '';
       } else {
-        this.appendToTagName(char);
+        if (!this.delegate.current().syntaxError && !isSpace(char)) {
+          this.appendToTagName(char);
+        }
       }
     },
 
@@ -480,13 +480,17 @@ export default class EventedTokenizer {
     },
 
     endTagOpen() {
-      let char = this.consume();
+      let char = this.peek();
 
       if (char === '@' || char === ':' || isAlpha(char)) {
+        this.consume();
         this.transitionTo(TokenizerState.endTagName);
         this.tagNameBuffer = '';
         this.delegate.beginEndTag();
         this.appendToTagName(char);
+      } else {
+        this.transitionTo(TokenizerState.endTagName);
+        this.delegate.beginEndTag();
       }
     }
   };
diff --git a/src/types.ts b/src/types.ts
index 631a96d..4221f3d 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -64,6 +64,7 @@ export interface TokenMap {
 }
 
 export interface TokenizerDelegate {
+  current(): Token;
   reset(): void;
   finishData(): void;
   tagOpen(): void;
diff --git a/tests/tokenizer-tests.ts b/tests/tokenizer-tests.ts
index 98538f1..9fda089 100644
--- a/tests/tokenizer-tests.ts
+++ b/tests/tokenizer-tests.ts
@@ -31,9 +31,54 @@ QUnit.test('A simple closing tag', function(assert) {
   assert.deepEqual(tokens, [endTag('div')]);
 });
 
-QUnit.test('A simple closing tag with trailing spaces', function(assert) {
+QUnit.test('A closing tag cannot contain trailing spaces', function(assert) {
   let tokens = tokenize('</div   \t\n>');
-  assert.deepEqual(tokens, [endTag('div')]);
+  let output = [withSyntaxError(
+    'closing tag must only contain tagname',
+    endTag('div')
+  )];
+
+  assert.deepEqual(tokens, output);
+});
+
+QUnit.test('A closing tag cannot contain leading spaces', function(assert) {
+  let tokens = tokenize('</ div>');
+  let output = [withSyntaxError(
+    'closing tag must only contain tagname',
+    endTag('')
+  )];
+
+  assert.deepEqual(tokens, output);
+});
+
+QUnit.test('A closing tag cannot contain an attribute', function(assert) {
+  let tokens = tokenize('</div foo="bar">');
+  let output = [withSyntaxError(
+    'closing tag must only contain tagname',
+    endTag('div')
+  )];
+
+  assert.deepEqual(tokens, output);
+});
+
+QUnit.test('A closing tag cannot contain multiple attributes', function(assert) {
+  let tokens = tokenize('</div foo="bar" foo="baz">');
+  let output = [withSyntaxError(
+    'closing tag must only contain tagname',
+    endTag('div')
+  )];
+
+  assert.deepEqual(tokens, output);
+});
+
+QUnit.test('A closing tag cannot be self-closing', function(assert) {
+  let tokens = tokenize('</div/>');
+  let output = [withSyntaxError(
+    'closing tag cannot be self-closing',
+    endTag('div')
+  )];
+
+  assert.deepEqual(tokens, output);
 });
 
 QUnit.test('A pair of hyphenated tags', function(assert) {