diff --git a/common/src/main/java/org/red5/server/service/ReflectionUtils.java b/common/src/main/java/org/red5/server/service/ReflectionUtils.java
index 8733586939a19bb665d41e1ceccb62114f250902..9a3f914bdadf9222ce868f33ad054da0493460f8 100644
--- a/common/src/main/java/org/red5/server/service/ReflectionUtils.java
+++ b/common/src/main/java/org/red5/server/service/ReflectionUtils.java
@@ -92,7 +92,7 @@ public class ReflectionUtils {
                     try {
                         Object[] convertedArgs = ConversionUtils.convertParams(args, paramTypes);
                         if (isTrace) {
-                            log.trace("Method {} matched - parameters: {}", methodName, paramTypes);
+                            log.trace("Found method {} {} - parameters: {}", methodName, method, paramTypes);
                         }
                         methodResult = new Object[] { method, convertedArgs };
                         break;
@@ -101,6 +101,9 @@ public class ReflectionUtils {
                     }
                 }
             }
+            if (isTrace) {
+                log.trace("Method name: {} result: {}", methodName, methodResult[0]);
+            }
         }
         return methodResult;
     }
@@ -118,6 +121,14 @@ public class ReflectionUtils {
         if (isDebug) {
             log.debug("Find method: {} in service: {} for call: {} and connection: {}", methodName, service, call, conn);
         }
+        // return value(s)
+        Object[] methodResult = NULL_RETURN;
+        // clear any previous exception from the call as it may be reused
+        if (call.getException() != null) {
+            log.debug("Clearing status and exception from call: {}", call);
+            call.setStatus(Call.STATUS_PENDING);
+            call.setException(null);
+        }
         // get the arguments
         final Object[] args = call.getArguments();
         // convert the args to their class types
@@ -138,8 +149,6 @@ public class ReflectionUtils {
         } else {
             argsWithConnection = conn != null ? new Object[] { conn } : new Object[0];
         }
-        // return value(s)
-        Object[] methodResult = NULL_RETURN;
         // get all the name matched methods once, then filter out the ones that contain a $
         final Set<Method> methods = Arrays.stream(service.getClass().getMethods()).filter(m -> (m.getName().equals(methodName) && !m.getName().contains("$"))).filter(m -> m.getParameterCount() == 1 || m.getParameterCount() == callParams.length || m.getParameterCount() == (callParams.length + 1)).collect(Collectors.toUnmodifiableSet());
         if (methods.isEmpty()) {
@@ -182,7 +191,7 @@ public class ReflectionUtils {
                     try {
                         Object[] convertedArgs = ConversionUtils.convertParams(args, paramTypes);
                         if (isTrace) {
-                            log.trace("Method {} matched - parameters: {}", methodName, paramTypes);
+                            log.trace("Found method {} {} - parameters: {}", methodName, method, paramTypes);
                         }
                         methodResult = new Object[] { method, convertedArgs };
                         break;
@@ -196,7 +205,7 @@ public class ReflectionUtils {
                     try {
                         Object[] convertedArgs = ConversionUtils.convertParams(argsWithConnection, paramTypes);
                         if (isTrace) {
-                            log.trace("Method {} matched - parameters: {}", methodName, paramTypes);
+                            log.trace("Found method {} {} - parameters: {}", methodName, method, paramTypes);
                         }
                         methodResult = new Object[] { method, convertedArgs };
                         break;
@@ -205,6 +214,9 @@ public class ReflectionUtils {
                     }
                 }
             }
+            if (isTrace) {
+                log.trace("Method name: {} result: {}", methodName, methodResult[0]);
+            }
             if (methodResult[0] == null) {
                 log.warn("Method {} not found in {} with parameters {}", methodName, service, Arrays.asList(callParams));
                 call.setStatus(Call.STATUS_METHOD_NOT_FOUND);
diff --git a/common/src/main/java/org/red5/server/service/ServiceInvoker.java b/common/src/main/java/org/red5/server/service/ServiceInvoker.java
index cbe13c80b40c339c49d5ce8a9419a353a070ee1e..839c33a33372d25fcede5f7782642e63fff25061 100644
--- a/common/src/main/java/org/red5/server/service/ServiceInvoker.java
+++ b/common/src/main/java/org/red5/server/service/ServiceInvoker.java
@@ -110,15 +110,20 @@ public class ServiceInvoker implements IServiceInvoker {
             log.debug("Method name contained an illegal prefix, it will be removed: {}", methodName);
             methodName = methodName.substring(1);
         }
+        if (log.isTraceEnabled()) {
+            log.trace("Method: {} call exception: ", methodName, call.getException());
+        }
         // look up the method with provided matching arguments
         Object[] methodResult = ReflectionUtils.findMethod(conn, call, service, methodName);
-        // get the method
-        Method method = (methodResult != null ? (Method) methodResult[0] : null);
-        if (method == null || call.getException() != null) {
+        // get the method from the result, methodResult itself cannot be null!
+        Method method = (Method) methodResult[0];
+        // checking  "|| call.getException() != null" here causes a reused call to fail if a previous attempt failed
+        if (method == null) {
             log.warn("Method not found: {}", methodName);
         } else {
             log.debug("Method found: {}", methodName);
             // get the parameters; the value at index 1 can be null, but the methodResult array will never be null
+            @SuppressWarnings("null")
             Object[] params = (Object[]) methodResult[1];
             try {
                 /* XXX(paul) legacy flash logic for restricting access to methods
@@ -137,13 +142,13 @@ public class ServiceInvoker implements IServiceInvoker {
                 Object result = null;
                 log.debug("Invoking method: {}", method.toString());
                 if (method.getReturnType().equals(Void.TYPE)) {
-                    log.debug("result: void");
                     method.invoke(service, params);
                     call.setStatus(Call.STATUS_SUCCESS_VOID);
+                    log.debug("result: void");
                 } else {
                     result = method.invoke(service, params);
-                    log.debug("result: {}", result);
                     call.setStatus(result == null ? Call.STATUS_SUCCESS_NULL : Call.STATUS_SUCCESS_RESULT);
+                    log.debug("result: {}", result);
                 }
                 if (call instanceof IPendingServiceCall) {
                     ((IPendingServiceCall) call).setResult(result);