{"record":{"id":"6d31c0af01e411bb","repo":"apache/hadoop","slug":"cannot-serialize-field-into-json","errorCode":null,"errorMessage":"Cannot serialize field {} into JSON","messagePattern":"Cannot serialize field (.+?) into JSON","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/metrics/RBFMetrics.java","lineNumber":1004,"sourceCode":"   *\n   * @return Map representing the data for the JSON representation.\n   */\n  private static Map<String, Object> getJson(BaseRecord record) {\n    Map<String, Object> json = new HashMap<>();\n    Map<String, Class<?>> fields = getFields(record);\n\n    for (String fieldName : fields.keySet()) {\n      if (!fieldName.equalsIgnoreCase(\"proto\")) {\n        try {\n          Object value = getField(record, fieldName);\n          if (value instanceof BaseRecord) {\n            BaseRecord recordField = (BaseRecord) value;\n            json.putAll(getJson(recordField));\n          } else {\n            json.put(fieldName, value == null ? JSONObject.NULL : value);\n          }\n        } catch (Exception e) {\n          throw new IllegalArgumentException(\n              \"Cannot serialize field \" + fieldName + \" into JSON\");\n        }\n      }\n    }\n    return json;\n  }\n\n  /**\n   * Returns all serializable fields in the object.\n   *\n   * @return Map with the fields.\n   */\n  private static Map<String, Class<?>> getFields(BaseRecord record) {\n    Map<String, Class<?>> getters = new HashMap<>();\n    for (Method m : record.getClass().getDeclaredMethods()) {\n      if (m.getName().startsWith(\"get\")) {\n        try {\n          Class<?> type = m.getReturnType();","sourceCodeStart":986,"sourceCodeEnd":1022,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/metrics/RBFMetrics.java#L986-L1022","documentation":"RBFMetrics.getJson() serializes a BaseRecord (e.g. RouterState, MountTable, MembershipState) into a JSONObject for JMX output by reflectively reading every declared field. If reading any field via getField(record, fieldName) throws (inaccessible field, incompatible type in the record, or a nested value that fails conversion), it rethrows IllegalArgumentException('Cannot serialize field <name> into JSON'). The original exception is deliberately swallowed, so the field name in the message is your only clue.","triggerScenarios":"JMX queries on RBFMetrics that dump state-store records, e.g. getRouters(), getMountTable(), getNameservices(), getNamenodeRegistrations() returning records whose fields include enums/Date/nested BaseRecords the reflective reader cannot handle; a custom BaseRecord subclass registered in the state store whose field types break getField(); accessing a field on a partially-updated record.","commonSituations":"Scraping RBF JMX beans with monitoring after adding a custom record type or after a Hadoop version change altered record schemas; records loaded from an older state-store driver (serialization version mismatch); reflective access blocked under stricter JRE module rules.","solutions":["Identify the failing field from the message and inspect that field's type in the corresponding BaseRecord class","If the field is a custom type, implement/verify its serialization support (make it a BaseRecord, String-primitive, or add a getter the serializer uses)","Check for state-store schema/version drift after upgrade: refresh records (e.g. re-register Router/NN heartbeats) so new-format records replace old ones","As a maintainer, chain the cause: throw new IllegalArgumentException(msg, e) to expose the root reason"],"exampleFix":"// before\n} catch (Exception e) {\n  throw new IllegalArgumentException(\n      \"Cannot serialize field \" + fieldName + \" into JSON\");\n}\n\n// after (preserves root cause)\n} catch (Exception e) {\n  throw new IllegalArgumentException(\n      \"Cannot serialize field \" + fieldName + \" into JSON\", e);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  String json = routerMetrics.getNamenodeRegistrations(); // any record-dumping JMX attr\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Cannot serialize field\")) {\n    // extract field name, inspect that BaseRecord field's type; likely schema drift or custom type\n    LOG.warn(\"JMX record serialization failed: {}\", e.getMessage());\n  } else { throw e; }\n}","preventionTips":["Keep custom state-store record fields to String/primitives or nested BaseRecord types","Re-register records (restart routers/namenodes) after upgrades so stale-format records are refreshed","When patching, chain the cause exception so diagnosis does not depend on the field name alone"],"tags":["hdfs","router-based-federation","jmx","serialization","reflection","state-store"],"backgroundTag":"json-serialization-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}