diff --git a/manual/luatex-fonts.tex b/manual/luatex-fonts.tex
index 294b1281ff1e2656201d712fd0be65ca24cb2195..41570ac05499be10f8f9f8b79b9ff199216bbb08 100644
--- a/manual/luatex-fonts.tex
+++ b/manual/luatex-fonts.tex
@@ -1,4 +1,4 @@
-% language=uk engine=luatex
+% language=us engine=luatex runpath=texruns:manuals/luatex
 
 \environment luatex-style
 
@@ -906,6 +906,28 @@ so called init and select discretionaries.
 
 \stopsubsection
 
+\startsubsection[title={\type {\tracinglostchars}}]
+
+This tracer reports missing characters. By design we delay this till the backend
+included them, when math typesetting needs them, or when a virtual font is
+created (1, 2, 3). Per request of the \LATEX\ team we have two extra options that
+report in an earlier stage i.e.\ when the glyphs are packaged or processed during
+line breaking (4 and 5).
+
+\starttabulate[|r|l|]
+    \DB     \BC effect \NC \NR
+    \TB
+    \NC 0   \NC nothing \NC \NR
+    \NC 1   \NC warning only to log file \NC \NR
+    \NC 2   \NC warning and force terminal \NC \NR
+    \NC 3   \NC error \NC \NR
+    \NC 4   \NC early warning (and force terminal) \NC \NR
+    \NC > 4 \NC early error \NC \NR
+    \LL
+\stoptabulate
+
+\stopsubsection
+
 \stopsection
 
 \stopchapter
diff --git a/manual/luatex.pdf b/manual/luatex.pdf
index b5a875b4a0f7b4a29d8af7777452a0b350aa91a7..27ea86b82925f932c3478f57f99c2061d51f0e28 100644
Binary files a/manual/luatex.pdf and b/manual/luatex.pdf differ
diff --git a/manual/luatex.tex b/manual/luatex.tex
index 0bcb9e76196b08f83c2be7e585c17f8b9f17c5d6..d2453f8a9fbd1ccdcadf8b249b714b8a7e731f11 100644
--- a/manual/luatex.tex
+++ b/manual/luatex.tex
@@ -73,7 +73,7 @@
 \startdocument
   [manual=Lua\TeX,
    status=stable,
-   version=1.20]
+   version=1.21]
 
 \startnotmode[*export]
     \component luatex-titlepage
diff --git a/source/texk/web2c/luatexdir/luatex_svnversion.h b/source/texk/web2c/luatexdir/luatex_svnversion.h
index 30b2ccffebd7a32d350421294ad9ab590561b66b..0f88a0707b226bcffc8eaa8bc6255fb23c02b4dd 100644
--- a/source/texk/web2c/luatexdir/luatex_svnversion.h
+++ b/source/texk/web2c/luatexdir/luatex_svnversion.h
@@ -1,4 +1,4 @@
 #ifndef luatex_svn_revision_h
 #define luatex_svn_revision_h
-#define luatex_svn_revision 7661
+#define luatex_svn_revision 7662
 #endif
diff --git a/source/texk/web2c/luatexdir/tex/errors.c b/source/texk/web2c/luatexdir/tex/errors.c
index 5246940482459f25655253aaef3cff11b2953cef..841f2f41e18123ce58d79984cef8282e3be76506 100644
--- a/source/texk/web2c/luatexdir/tex/errors.c
+++ b/source/texk/web2c/luatexdir/tex/errors.c
@@ -935,16 +935,22 @@ suppressed it.
 If |tracing_lost_chars_par| (i.e. \.{\\tracinglostchar})  is  greater than 2,
 it's considered as an error.
 
+=0 : nothing 
+=1 : warning only to log file
+=2 : warning + force terminal 
+=3 : error                      
+=4 : warning (+ force terminal) : per request latex team
+>4 : error                      : per request latex team
+
 */
 
 void char_warning(internal_font_number f, int c)
 {
-    /*tex saved value of |tracing_online| */
-    int old_setting;
-    /* index to current digit; we assume that $0\L n<16^{22}$ */
-    int k;
     if (tracing_lost_chars_par > 0) {
-        old_setting = tracing_online_par;
+        /*tex saved value of |tracing_online| */
+        int old_setting = tracing_online_par;
+        /* index to current digit; we assume that $0\L n<16^{22}$ */
+        int k;
         if (tracing_lost_chars_par > 1)
             tracing_online_par = 1;
         begin_diagnostic();
@@ -970,7 +976,9 @@ void char_warning(internal_font_number f, int c)
         end_diagnostic(false);
         tracing_online_par = old_setting;
     }
-    if (tracing_lost_chars_par > 2) {
+    if (tracing_lost_chars_par == 3) {
+       error();
+    } else if (tracing_lost_chars_par > 4) {
        error();
     }
 }
diff --git a/source/texk/web2c/luatexdir/tex/linebreak.c b/source/texk/web2c/luatexdir/tex/linebreak.c
index 646a5a771f7702e633c29576e2e89acd6ec02a4c..9c3279a2e6c92d817edcc051dfa984bde49f35a4 100644
--- a/source/texk/web2c/luatexdir/tex/linebreak.c
+++ b/source/texk/web2c/luatexdir/tex/linebreak.c
@@ -958,6 +958,9 @@ static void add_to_widths(halfword s, int line_break_dir, int adjust_spacing, sc
 {
     while (s != null) {
         if (is_char_node(s)) {
+if (tracing_lost_chars_par > 3 && ! char_exists(font(s), character(s))) {
+    char_warning(font(s), character(s));
+}
             widths[1] += pack_width(line_break_dir, dir_TRT, s, true);
             if ((adjust_spacing > 1) && check_expand_pars(font(s))) {
                 set_prev_char_p(s);
@@ -1004,6 +1007,9 @@ static void sub_from_widths(halfword s, int line_break_dir, int adjust_spacing,
     while (s != null) {
         /*tex Subtract the width of node |s| from |break_width|; */
         if (is_char_node(s)) {
+if (tracing_lost_chars_par > 3 && ! char_exists(font(s), character(s))) {
+    char_warning(font(s), character(s));
+}
             widths[1] -= pack_width(line_break_dir, dir_TRT, s, true);
             if ((adjust_spacing > 1) && check_expand_pars(font(s))) {
                 set_prev_char_p(s);
@@ -2135,6 +2141,9 @@ void ext_do_line_break(
                     |vlink(cur_p)=null| when |cur_p| is a character node.
 
                 */
+if (tracing_lost_chars_par > 3 && ! char_exists(font(cur_p), character(cur_p))) {
+    char_warning(font(cur_p), character(cur_p));
+}
                 active_width[1] += pack_width(line_break_dir, dir_TRT, cur_p, true);
                 if ((adjust_spacing > 1) && check_expand_pars(font(cur_p))) {
                     set_prev_char_p(cur_p);
diff --git a/source/texk/web2c/luatexdir/tex/packaging.c b/source/texk/web2c/luatexdir/tex/packaging.c
index c69f65d7aa8a9d0bddfa10a6678c41585a0d944e..238beb336abcf84b5b11dad6c45a1c63ea7e7373 100644
--- a/source/texk/web2c/luatexdir/tex/packaging.c
+++ b/source/texk/web2c/luatexdir/tex/packaging.c
@@ -411,20 +411,32 @@ void do_subst_font(halfword p, int ex_ratio)
     if (type(p) == disc_node) {
         halfword r = vlink(pre_break(p));
         while (r != null) {
-            if (is_char_node(r))
+            if (is_char_node(r)) {
+if (tracing_lost_chars_par > 3 && ! char_exists(font(r), character(r))) {
+    char_warning(font(r), character(r));
+}
                 do_subst_font(r, ex_ratio);
+            }
             r = vlink(r);
         }
         r = vlink(post_break(p));
         while (r != null) {
-            if (is_char_node(r))
+            if (is_char_node(r)) {
+if (tracing_lost_chars_par > 3 && ! char_exists(font(r), character(r))) {
+    char_warning(font(r), character(r));
+}
                 do_subst_font(r, ex_ratio);
+            }
             r = vlink(r);
         }
         r = vlink(no_break(p));
         while (r != null) {
-            if (is_char_node(r))
+            if (is_char_node(r)) {
+if (tracing_lost_chars_par > 3 && ! char_exists(font(r), character(r))) {
+    char_warning(font(r), character(r));
+}
                 do_subst_font(r, ex_ratio);
+            }
             r = vlink(r);
         }
         return;
@@ -620,6 +632,9 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction)
                 these instructions to be exercised one more time.
 
             */
+if (tracing_lost_chars_par > 3 && ! char_exists(font(p), character(p))) {
+    char_warning(font(p), character(p));
+}
             if (m >= cal_expand_ratio) {
                 prev_char_p = p;
                 if (m == cal_expand_ratio) {
@@ -1070,6 +1085,9 @@ scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, int g_sign,
     }
     while (p != pp && p != null) {
         while (is_char_node(p) && p != pp) {
+if (tracing_lost_chars_par > 3 && ! char_exists(font(p), character(p))) {
+    char_warning(font(p), character(p));
+} 
             whd = pack_width_height_depth(hpack_dir, dir_TRT, p, true);
             siz.wd += whd.wd;
             if (whd.ht > siz.ht)