Repository: xroche/httrack (2026-07-27T11:39:52Z)

Issue:
The -o help text promises a generated error page; the engine stores the server's
`src/htshelp.c:563` describes `-o` as "generate output html file in case of error (404..)". The same line is regenerated into `man/httrack.1:223` and `html/httrack.man.html`, and appears four times in `html/fcguide.html`.

The engine generates nothing. `opt->errpage` only decides whether the server's own error body survives: `htsparse.c:3781` sets `store_errpage`, which keeps `r.adr` alive so the normal save path writes it, and `htsparse.c:3825` frees it otherwise. `tests/23_local-errpage.test` asserts exactly that. The block that would have built a stand-in body never ran (dead since the 3.20.2 import) and was removed in #783, so nothing on either side of that PR ever produced a generated page.

The wording predates the current behaviour: the option got its meaning in aca2f4d, shipped in 3.46-1 as "generate error pages when needed", which was a change to the store path.

Worth rewording the help line and the man page to say the server's error page is kept rather than discarded. The `--generate-errors` / `--do-not-generate-errors` aliases and the translated GUI strings ("Do not create HTML error pages", 30 files) carry the same wording; renaming those is probably not worth the churn, but the C help string and the generated docs are cheap to correct.



Discussion:

Patch:
diff --git a/html/fcguide.html b/html/fcguide.html
index 0b22b465..f7a30e6f 100644
--- a/html/fcguide.html
+++ b/html/fcguide.html
@@ -237,7 +237,7 @@ <h2> Basics </h2>
   x  replace external html links by error pages (--replace-external)
  %x  do not include any password for external password protected websites (%x0 include) (--no-passwords)
  %q *include query string for local files (useless, for information purpose only) (%q0 don't include) (--include-query-string)
-  o *generate output html file in case of error (404..) (o0 don't generate) (--generate-errors)
+  o *save the server's error pages (404..) (o0 discard them) (--generate-errors)
   X *purge old files after update (X0 keep delete) (--purge-old[=N])
 
 Spider options:
@@ -413,7 +413,7 @@ <h2> Syntax </h2>
   NN  name conversion type (0 *original structure, 1+: see below)
   LN  long names (L1 *long names / L0 8-3 conversion)
   K   keep original links (e.g. http://www.adr/link) (K0 *relative link)
-  o *generate output html file in case of error (404..) (o0 don't generate)
+  o *save the server's error pages (404..) (o0 discard them)
   X *purge old files after update (X0 keep delete)
   bN  accept cookies in cookies.txt (0=do not accept,* 1=accept)
   u check document type if unknown (cgi,asp..) (u0 don't check, * u1 check but /, u2 check always)
@@ -473,11 +473,11 @@ <h2> Syntax </h2>
 URLs within this web site are adjusted to point to the files in the
 mirror.
 
-<pre><b><i>  o *generate output html file in case of error (404..) (o0 don't generate) </i></b></pre>
+<pre><b><i>  o *save the server's error pages (404..) (o0 discard them) </i></b></pre>
 
-<p align=justify> IF there are errors in downloading, create a file that
-indicates that the URL was not found.  This makes browsing go a lot
-smoother.
+<p align=justify> IF a page cannot be downloaded, the error page the
+server sent is saved in its place, so a broken link still lands on the
+site's own 'not found' page.  This makes browsing go a lot smoother.
 
 <pre><b><i>  X *purge old files after update (X0 keep delete) </i></b></pre>
 
@@ -1011,7 +1011,7 @@ <h3>Mirror Build Options</h3>
   LN  long names (L1 *long names / L0 8-3 conversion)
   K   keep original links (e.g. http://www.adr/link) (K0 *relative link)
   x   replace external html links by error pages
-  o *generate output html file in case of error (404..) (o0 don't generate)
+  o *save the server's error pages (404..) (o0 discard them)
   X *purge old files after update (X0 keep delete)
   %x  do not include any password for external password protected websites (%x0 include) (--no-passwords)
   %q *include query string for local files (information only) (%q0 don't include) (--include-query-string)
@@ -1118,9 +1118,9 @@ <h3>Mirror Build Options</h3>
 httrack http://www.shoesizes.com -O /tmp/shoesizes -x
 </i></b></pre>
 
-<p align=justify> This option prevents the generation of '404' error
-files to replace files that were not found even though there were URLs
-pointing to them.  It is useful for saving space as well as eliminating
+<p align=justify> This option keeps the server's '404' error pages out
+of the mirror, even though there were URLs pointing to the missing
+files.  It is useful for saving space as well as eliminating
 unnecessary files in operations where a working web site is not the
 desired result. 
 
diff --git a/html/httrack.man.html b/html/httrack.man.html
index 0dd8b13d..e2a19392 100644
--- a/html/httrack.man.html
+++ b/html/httrack.man.html
@@ -777,8 +777,8 @@ <h3>Build options:
 <td width="82%">
 
 
-<p>*generate output html file in case of error (404..) (o0
-don&rsquo;t generate) (--generate-errors)</p></td></tr>
+<p>*save the server&rsquo;s error pages (404..) (o0 discard
+them) (--generate-errors)</p></td></tr>
 <tr valign="top" align="left">
 <td width="9%"></td>
 <td width="4%">
diff --git a/html/step9_opt5.html b/html/step9_opt5.html
index 94bda2c6..30d91e74 100644
--- a/html/step9_opt5.html
+++ b/html/step9_opt5.html
@@ -122,7 +122,7 @@ <h2 align="center"><em>Option panel : Build</em></h2>
   </small><br><br>
 <!-- -->
   <li>No error pages</li>
-  <br><small>Do not generate error pages (if a 404 error occurred, for example)
+  <br><small>Do not save the error pages sent by the server (if a 404 error occurred, for example)
   <br>If a page is missing on the remote site, there will not be any warning on the local site
   </small><br><br>
 <!-- -->
diff --git a/man/httrack.1 b/man/httrack.1
index 0191e0c6..d883e123 100644
--- a/man/httrack.1
+++ b/man/httrack.1
@@ -3,7 +3,7 @@
 .\"
 .\" This file is generated by man/makeman.sh; do not edit by hand.
 .\" SPDX-License-Identifier: GPL-3.0-or-later
-.TH httrack 1 "26 July 2026" "httrack website copier"
+.TH httrack 1 "27 July 2026" "httrack website copier"
 .SH NAME
 httrack \- offline browser : copy websites to a local directory
 .SH SYNOPSIS
@@ -220,7 +220,7 @@ do not include any password for external password protected websites (%x0 includ
 .IP \-%g
 strip query keys for dedup ([host/pattern=]key1,key2,...) (\-\-strip\-query <param>)
 .IP \-o
-*generate output html file in case of error (404..) (o0 don't generate) (\-\-generate\-errors)
+*save the server's error pages (404..) (o0 discard them) (\-\-generate\-errors)
 .IP \-X
 *purge old files after update (X0 keep delete) (\-\-purge\-old[=N])
 .IP \-%p
diff --git a/src/htshelp.c b/src/htshelp.c
index a05b7aad..4237a126 100644
--- a/src/htshelp.c
+++ b/src/htshelp.c
@@ -558,8 +558,7 @@ void help(const char *app, int more) {
   infomsg
     (" %q *include query string for local files (useless, for information purpose only) (%q0 don't include)");
   infomsg(" %g  strip query keys for dedup ([host/pattern=]key1,key2,...)");
-  infomsg
-    ("  o *generate output html file in case of error (404..) (o0 don't generate)");
+  infomsg("  o *save the server's error pages (404..) (o0 discard them)");
   infomsg("  X *purge old files after update (X0 keep delete)");
   infomsg(" %p  preserve html files 'as is' (identical to '-K4 -%F \"\"')");
   infomsg(" %T  links conversion to UTF-8");


Test patch:
diff --git a/tests/23_local-errpage.test b/tests/23_local-errpage.test
index 32e5e621..0365968b 100644
--- a/tests/23_local-errpage.test
+++ b/tests/23_local-errpage.test
@@ -13,7 +13,10 @@ bash "$top_srcdir/tests/local-crawl.sh" --errors 1 \
     --not-found 'errpage/missing.html' \
     httrack 'BASEURL/errpage/index.html' '-o0'
 
-# Control -o1 (default): the 404 error page is written.
+# Control -o1 (default): the 404 body is the server's verbatim, no HTTrack marker (#787); good.html proves the marker check can fire.
 bash "$top_srcdir/tests/local-crawl.sh" --errors 1 \
     --found 'errpage/missing.html' \
+    --file-matches 'errpage/missing.html' '404 error body' \
+    --file-not-matches 'errpage/missing.html' 'HTTrack' \
+    --file-matches 'errpage/good.html' 'HTTrack' \
     httrack 'BASEURL/errpage/index.html' '-o1'