You need \makeatletter around \rhead{...}, not inside it, but you can do better.
There is no “official” interface for using \@abspage@last in the document, mainly because it's not meant to save the last page number, but the total number of pages, including those with different numbering scheme.
If you don't change numbering scheme, you can use it by first defining your own interface
\documentclass[a4paper]{article}
\usepackage{fancyhdr}
\makeatletter
\newcommand{\lastpagenumber}{@abspage@last}
\makeatother
\pagestyle{fancy}
\fancyhf{}
\rhead{Page \thepage\ of \lastpagenumber}
\begin{document}
First page:
\clearpage
Second page
\clearpage
Third page
\end{document}
The default value is 1073741823, which you will obtain when the .aux file doesn't yet exist.
If you want to be warned that a rerun is necessary, you can check whether \@abspage@last equals \maxdimen:
\documentclass[a4paper]{article}
\usepackage{fancyhdr}
\makeatletter
\newcommand{\lastpagenumber}{%
\ifnum@abspage@last=\maxdimen
@lastpagewarning
\else
@abspage@last
\fi
}
\newcommand{@lastpagewarning}{%
@latex@warning@no@line{Could not determine last page number, rerun LaTeX}%
??\gdef@lastpagewarning{??}%
}
\makeatother
\pagestyle{fancy}
\fancyhf{}
\rhead{Page \thepage\ of \lastpagenumber}
\begin{document}
First page:
\clearpage
Second page
\clearpage
Third page
\end{document}
If the .aux file is missing or, for some reason, \@abspage@last isn't yet defined, you will get
LaTeX Warning: Could not determine last page number, rerun LaTeX.
Of course this would fail if your document has 1073741823 pages, but…
\makeatletter\rhead{Page \thepage\ of \@abspage@last}\makeatother. You must change the catcode before the @ is seen by TeX. – Ulrike Fischer May 07 '22 at 08:57\rhead{Page \thepage\ of \makeatletter\@abspage@last\makeatother}, why does\makeatletternot change the catcode before the @ is seen by TeX? – lyl May 07 '22 at 15:17