I trace down to the while loop in nxml-forward-single-balanced-item: (defun nxml-forward-single-balanced-item () (condition-case err (goto-char (let ((end (nxml-token-after))) (save-excursion (while (eq xmltok-type 'space) (goto-char end) (setq end (nxml-token-after))) (cond ((/= (point) xmltok-start) In my test xml file, when the last comment char is deleted, `end' will be 65, then (nxml-token-after) also returns 65 , so this is a endless loop.