Why Enums Can Break RPC Calls and How to Avoid Them
An online service threw an IllegalArgumentException because a downstream system added a new enum constant without notifying dependent services, leading to deserialization failures in RPC calls; the article explains the root cause, JSON serialization behavior, and recommends using strings instead of enums for API parameters and return values.
Recently our production environment threw an IllegalArgumentException during execution. The stack trace showed the root cause:
java.lang.IllegalArgumentException:
No enum constant com.a.b.f.m.a.c.AType.P_MThe error indicates that the enum constant P_M could not be found in the AType enum.
Investigation revealed that a downstream system had released a new version of an API package, adding the P_M constant to the AType enum in an RPC response class. The downstream team did not inform us, so our service failed to deserialize the new value.
Problem Reproduction
The downstream system A provides an interface whose response contains an enum field:
public interface AFacadeService {
public AResponse doSth(ARequest aRequest);
}
public class AResponse {
private Boolean success;
private AType aType;
}
public enum AType {
P_T,
A_B
}System B depends on this library and calls the RPC method:
public class BService {
@Autowired
AFacadeService aFacadeService;
public void doSth() {
ARequest aRequest = new ARequest();
AResponse aResponse = aFacadeService.doSth(aRequest);
AType aType = aResponse.getAType();
}
}If both systems use the same version of the library, the enum values match and no issue occurs. However, when the library is upgraded in system A to add a new constant P_M while system B remains on the old version, deserialization fails because the JSON value cannot be mapped to the older enum definition, resulting in an IllegalArgumentException.
Root Cause Analysis
Most RPC frameworks serialize data as JSON. During deserialization, the JSON library calls Enum.valueOf to convert a string to an enum constant. If the constant is missing, Enum.valueOf throws an IllegalArgumentException:
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null) return result;
if (name == null) throw new NullPointerException("Name is null");
throw new IllegalArgumentException("No enum constant " + enumType.getCanonicalName() + "." + name);
}The Alibaba Java Development Manual even advises that enum types should not be used in API return values for exactly this reason.
Extended Thoughts
Why are enums acceptable for parameters but problematic for return values? Parameters are constructed by the caller, who can control which enum values are used. If the caller uses an older library, it simply cannot reference the new enum constant, so no mismatch occurs. Return values, however, are produced by the callee and may contain new constants unknown to the caller, leading to deserialization errors.
Using strings instead of enums for both request and response fields avoids this compatibility issue. The caller can still validate the string against the known enum values on the server side, and the server can evolve independently without forcing all clients to upgrade.
public class AResponse {
private Boolean success;
/** @see AType */
private String aType;
}In large organizations with many downstream consumers, requiring every client to upgrade whenever a library changes is unrealistic. Moreover, excessive dependencies slow down compilation and increase the risk of conflicts. Therefore, avoiding enums in public RPC interfaces improves stability and evolution flexibility.
In summary, while enums are useful internally, they should be avoided in the input and especially output of external APIs; using strings with documented allowed values is a safer alternative.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
