Netflix/Hystrix · error · FallbackDefinitionException

fallback method wasn't found: " + name + "(" + Arrays.toStri

Error message

fallback method wasn't found: " + name + "(" + Arrays.toString(fallbackParameterTypes) + ")"

What it means

MethodProvider (FallbackMethod.getFallbackMethod) locates the fallback method by name plus parameter types, trying both the plain signature (same params as the command) and the extended signature (params + trailing Throwable). If neither lookup succeeds — including the search up the class hierarchy — it throws FallbackDefinitionException('fallback method wasn't found: name(paramTypes...)') listing the exact signature it searched for.

Source

Thrown at hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/utils/MethodProvider.java:190

            if (isDefault()) {
                fallbackParameterTypes = new Class[0];
            } else {
                fallbackParameterTypes = commandMethod.getParameterTypes();
            }

            if (extended && fallbackParameterTypes[fallbackParameterTypes.length - 1] == Throwable.class) {
                fallbackParameterTypes = ArrayUtils.remove(fallbackParameterTypes, fallbackParameterTypes.length - 1);
            }

            Class<?>[] extendedFallbackParameterTypes = Arrays.copyOf(fallbackParameterTypes,
                    fallbackParameterTypes.length + 1);
            extendedFallbackParameterTypes[fallbackParameterTypes.length] = Throwable.class;

            Optional<Method> exFallbackMethod = getMethod(enclosingType, name, extendedFallbackParameterTypes);
            Optional<Method> fMethod = getMethod(enclosingType, name, fallbackParameterTypes);
            Method method = exFallbackMethod.or(fMethod).orNull();
            if (method == null) {
                throw new FallbackDefinitionException("fallback method wasn't found: " + name + "(" + Arrays.toString(fallbackParameterTypes) + ")");
            }
            return new FallbackMethod(method, exFallbackMethod.isPresent(), isDefault());
        }

    }


    /**
     * Gets method by name and parameters types using reflection,
     * if the given type doesn't contain required method then continue applying this method for all super classes up to Object class.
     *
     * @param type           the type to search method
     * @param name           the method name
     * @param parameterTypes the parameters types
     * @return Some if method exists otherwise None
     */
    public static Optional<Method> getMethod(Class<?> type, String name, Class<?>... parameterTypes) {
        Method[] methods = type.getDeclaredMethods();

View on GitHub (pinned to 5ce3bc58c3)

Solutions

  1. Copy the exact expected signature from the error message and implement the fallback with exactly those parameter types (optionally plus a trailing Throwable)
  2. Verify the method name string in fallbackMethod matches character-for-character (it is not validated at compile time)
  3. Keep the fallback in the same class (or an ancestor) with sufficient visibility and matching static-ness
  4. Add a CI test that invokes each command once so missing fallbacks fail the build, not production

Example fix

// before
@HystrixCommand(fallbackMethod = "getUserFallback")
public User getUser(String id, boolean cached) { ... }

private User getUserFallback(String id) { ... }

// after
@HystrixCommand(fallbackMethod = "getUserFallback")
public User getUser(String id, boolean cached) { ... }

private User getUserFallback(String id, boolean cached, Throwable e) { ... }
Defensive patterns

Strategy: validation

Validate before calling

String name = ann.fallbackMethod();
boolean found = false;
for (Method fm : clazz.getDeclaredMethods()) {
  if (!fm.getName().equals(name)) continue;
  Class<?>[] fp = fm.getParameterTypes();
  boolean plain = Arrays.equals(fp, commandMethod.getParameterTypes());
  boolean extended = Arrays.equals(
      Arrays.copyOf(fp, fp.length - 1), commandMethod.getParameterTypes())
      && fp[fp.length - 1] == Throwable.class;
  found |= plain || extended;
}
if (!found) throw new IllegalStateException("Missing/incorrect fallback: " + name);

Try / catch

catch (FallbackDefinitionException e) { log.error("{}", e.getMessage()); /* message shows exact expected signature — implement it */ }

Prevention

When it happens

Trigger: Declaring @HystrixCommand(fallbackMethod = "getUserFallback") but the method does not exist, has a misspelled name, has a different parameter list (extra param not Throwable, different order/types), is private in another class, or the Throwable overload has the exception parameter in a non-trailing position.

Common situations: Renaming the fallback method without updating fallbackMethod; adding a parameter to the command method but not the fallback; fallback defined in a parent class with different visibility; overloading fallbacks and expecting Javanica to pick by best match (it requires an exact match).

Related errors


AI-assisted analysis of Netflix/Hystrix@5ce3bc58c3 (2026-08-14). Data as JSON: /api/errors/cd86f2ac3414da07. Report an issue: GitHub.