Index: generic/nsf.c
===================================================================
diff -u -r43373d98ca07d446abec8f8f62af7c4df56207a3 -r91e563cefe5477b877817b11c00c2e113bcb12b2
--- generic/nsf.c	(.../nsf.c)	(revision 43373d98ca07d446abec8f8f62af7c4df56207a3)
+++ generic/nsf.c	(.../nsf.c)	(revision 91e563cefe5477b877817b11c00c2e113bcb12b2)
@@ -10877,7 +10877,7 @@
   result = CheckConditionInScope(interp, guardObj);
   rst->guardCount--;
 
-  /*fprintf(stderr, "checking guard **%s** returned rc=%d\n", ObjStr(guardObj), rc);*/
+  /*fprintf(stderr, "checking guard **%s** returned rc=%d\n", ObjStr(guardObj), result);*/
 
   if (likely(result == TCL_OK)) {
     /* fprintf(stderr, " +++ OK\n"); */
@@ -14295,9 +14295,11 @@
            * stack, we pass it already to search-and-invoke.
            */
 
-          /*fprintf(stderr, "... calling nextmethod cscPtr %p\n", (void *)cscPtr);*/
+          cscPtr->flags |= NSF_CSC_CALL_IS_GUARD;
+          /*fprintf(stderr, "... guard fail calling nextmethod for '%s' cscPtr %p\n", methodName, (void *)cscPtr);*/
           result = NextSearchAndInvoke(interp, methodName, objc, objv, cscPtr, NSF_FALSE);
-          /*fprintf(stderr, "... after nextmethod result %d\n", result);*/
+          /*fprintf(stderr, "... guard fail nextmethod for '%s' result %d\n", methodName, result);*/
+          cscPtr->flags &= ~ NSF_CSC_CALL_IS_GUARD;
         }
 
         /*
@@ -14386,6 +14388,7 @@
                       NULL);
     cscPtr->flags |= NSF_CSC_CALL_IS_NRE;
     result = TclNRInterpProcCore(interp, objv[0], 1, &MakeProcError);
+
 #else
     ClientData data[3] = {
       (releasePc ? pcPtr : NULL),
@@ -15269,7 +15272,7 @@
   flags = cscPtr->flags;
   rst = RUNTIME_STATE(interp);
 
-  /*fprintf(stderr, "ObjectDispatchFinalize %p %s flags %.6x (%d) frame %.6x unk %d m %s\n",
+  /*fprintf(stderr, "ObjectDispatchFinalize %p %s flags %.6x (result %d) frame %.6x unk %d m %s\n",
           (void*)cscPtr, ObjectName(object), flags,
           result, cscPtr->frameType, RUNTIME_STATE(interp)->unknown,
           (cscPtr->cmdPtr != NULL) ? Tcl_GetCommandName(interp, cscPtr->cmdPtr) : "");*/
@@ -15829,7 +15832,7 @@
 
         cmd = FilterSearchProc(interp, object, &object->filterStack->currentCmdPtr, &class);
         if (cmd != NULL) {
-          /*fprintf(stderr, "*** filterSearchProc returned cmd %p\n", cmd);*/
+          /*fprintf(stderr, "*** filterSearchProc returned cmd %p\n", (void*)cmd);*/
           frameType = NSF_CSC_TYPE_ACTIVE_FILTER;
           methodName = (char *)Tcl_GetCommandName(interp, cmd);
           flags |= NSF_CM_IGNORE_PERMISSIONS;
@@ -16511,8 +16514,10 @@
   unknownObj = NsfMethodObj(object, NSF_o_unknown_idx);
 
   /*fprintf(stderr, "compare unknownObj %p with methodObj %p '%s' %p %p %s -- %s\n",
-    unknownObj, methodObj, ObjStr(methodObj), callInfoObj, (callInfoObj != NULL) ?objv[1]:NULL, (callInfoObj != NULL) ?ObjStr(objv[1]) : NULL,
-    methodName);*/
+          unknownObj, methodObj, ObjStr(methodObj), callInfoObj,
+          (callInfoObj != NULL) ? objv[1] : NULL,
+          (callInfoObj != NULL) ? ObjStr(objv[1]) : NULL,
+          methodName);*/
 
   if ((unknownObj != NULL)
       && (methodObj != unknownObj)
@@ -20455,7 +20460,7 @@
         endOfChain = NSF_TRUE;
         *endOfFilterChain = NSF_TRUE;
         *classPtr = NULL;
-        /*fprintf(stderr, "EndOfChain resetting cl\n");*/
+        /*fprintf(stderr, "EndOfChain resetting cl, new methodName '%s'\n", *methodNamePtr);*/
       }
     } else {
       *methodNamePtr = (char *) Tcl_GetCommandName(interp, *cmdPtr);
@@ -20553,7 +20558,7 @@
                                   (cscPtr->frameType == NSF_CSC_TYPE_ACTIVE_FILTER) != 0u)
                                  ? 0 : NSF_CMD_CALL_PRIVATE_METHOD);
     } else {
-    *classPtr = NULL;
+      *classPtr = NULL;
     }
 
   } else {
@@ -20823,9 +20828,15 @@
 #if 0
   Tcl_ResetResult(interp); /* needed for bytecode support */
 #endif
-  if (cmd != NULL) {
+
+  if (likely(cmd != NULL)
+      || ( endOfFilterChain
+           && (cscPtr->objv != NULL)
+           && (cscPtr->flags & NSF_CSC_CALL_IS_GUARD) != 0u )
+     ) {
     unsigned short frameType = NSF_CSC_TYPE_PLAIN;
 
+
     /*
      * Change mixin state.
      */
@@ -20845,9 +20856,10 @@
     /*
      * Change filter state
      */
+
     if (object->filterStack != NULL) {
       if (cscPtr->frameType == NSF_CSC_TYPE_ACTIVE_FILTER) {
-        /*fprintf(stderr, "next changes filter state\n");*/
+        /*fprintf(stderr, "next changes filter state cmd %p\n", (void*)cmd);*/
         cscPtr->frameType = NSF_CSC_TYPE_INACTIVE_FILTER;
       }
 
@@ -20861,6 +20873,19 @@
       }
     }
 
+    if (cmd == NULL) {
+      /*
+       * The cmd was not found by NextSearchMethod(). In case of
+       * end-of-filterchain in a filter guard call, we have to call the "unknown"
+       * method, since otherwise we cannot flag unknown methods behind
+       * filters.
+       */
+      result = DispatchUnknownMethod(interp, object,
+                                     cscPtr->objc, cscPtr->objv, NULL, cscPtr->objv[0],
+                                     (cscPtr->flags & NSF_CSC_CALL_NO_UNKNOWN)|NSF_CSC_IMMEDIATE);
+      goto next_search_and_invoke_cleanup;
+    }
+
     /*
      * Now actually call the "next" method.
      */
@@ -20931,7 +20956,15 @@
     /* NsfShowStack(interp);*/
 
     topCscPtr = CallStackGetTopFrame(interp, &varFramePtr);
-    assert(topCscPtr != NULL);
+    if (topCscPtr == NULL) {
+      /*
+       * This might happen, when after a filter chain the method to be called
+       * is not found.
+       */
+      /* fprintf(stderr, "no topCscPtr, unknown %d result %d\n", rst->unknown, result);*/
+      goto next_search_and_invoke_cleanup;
+    }
+
     assert(varFramePtr != NULL);
 
     /*
@@ -31376,7 +31409,9 @@
       Tcl_SetObjResult(interp,
                        Tcl_NewStringObj(MethodName(cscPtr->filterStackEntry->calledProc), TCL_INDEX_NONE));
     } else {
-      result = NsfPrintError(interp, "called from outside of a filter");
+        NsfShowStack(interp);
+
+      result = NsfPrintError(interp, "called from outside of a filter 1");
     }
     break;
 
Index: library/xotcl/tests/testx.xotcl
===================================================================
diff -u -rc493c042822de99268d18a994840c9bf32ee36a1 -r91e563cefe5477b877817b11c00c2e113bcb12b2
--- library/xotcl/tests/testx.xotcl	(.../testx.xotcl)	(revision c493c042822de99268d18a994840c9bf32ee36a1)
+++ library/xotcl/tests/testx.xotcl	(.../testx.xotcl)	(revision 91e563cefe5477b877817b11c00c2e113bcb12b2)
@@ -4403,7 +4403,20 @@
 }
 
 o test
+o destroy
 
+Object create o
+
+o proc f1 {} { return 1 }
+o proc f2 {} { return 2 }
+o filter {{f1 -guard {
+    [self calledproc] == "c"
+}}}
+
+errorCheck [o f2] 2 "call existing method after all guards failed"
+errorCheck [catch {o XXXXX} errorMsg] 1 "call non-existing method after all guards failed -> error"
+errorCheck $errorMsg "::o: unable to dispatch method 'XXXXX'" "call non-existing method after all guards failed -> errorMsg"
+
 puts "PASSED ::topLevelCommands"
 
 #