This is a known problem as made evident in a comment in whitespace.el
:
(defcustom whitespace-display-mappings
'(
(space-mark ?\ [?\u00B7] [?.]) ; space - centered dot
(space-mark ?\xA0 [?\u00A4] [?_]) ; hard space - currency
;; NEWLINE is displayed using the face `whitespace-newline'
(newline-mark ?\n [?$ ?\n]) ; eol - dollar sign
;; (newline-mark ?\n [?\u21B5 ?\n] [?$ ?\n]) ; eol - downwards arrow
;; (newline-mark ?\n [?\u00B6 ?\n] [?$ ?\n]) ; eol - pilcrow
;; (newline-mark ?\n [?\u00AF ?\n] [?$ ?\n]) ; eol - overscore
;; (newline-mark ?\n [?\u00AC ?\n] [?$ ?\n]) ; eol - negation
;; (newline-mark ?\n [?\u00B0 ?\n] [?$ ?\n]) ; eol - degrees
;;
;; WARNING: the mapping below has a problem.
;; When a TAB occupies exactly one column, it will display the
;; character ?\xBB at that column followed by a TAB which goes to
;; the next TAB column.
;; If this is a problem for you, please, comment the line below.
(tab-mark ?\t [?\u00BB ?\t] [?\\ ?\t]) ; tab - left quote mark
)
...)
Considering that a display mapping introduces an extra preceding character, I don't see any way of solving this with whitespace-mode's current mode of operation. Try using the described workaround instead.