{"record":{"id":"c898f91db6e1b627","repo":"apache/hadoop","slug":"error-stringify-config","errorCode":null,"errorMessage":"Error stringify config","messagePattern":"Error stringify config","errorType":"exception","errorClass":"MetricsConfigException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/impl/MetricsSystemImpl.java","lineNumber":355,"sourceCode":"      sa.startMBeans();\n    }\n  }\n\n  @Override\n  public synchronized void stopMetricsMBeans() {\n    for (MetricsSourceAdapter sa : sources.values()) {\n      sa.stopMBeans();\n    }\n  }\n\n  @Override\n  public synchronized String currentConfig() {\n    PropertiesConfiguration saver = new PropertiesConfiguration();\n    StringWriter writer = new StringWriter();\n    saver.copy(config);\n    try { saver.write(writer); }\n    catch (Exception e) {\n      throw new MetricsConfigException(\"Error stringify config\", e);\n    }\n    return writer.toString();\n  }\n\n  private synchronized void startTimer() {\n    if (timer != null) {\n      LOG.warn(prefix +\" metrics system timer already started!\");\n      return;\n    }\n    logicalTime = 0;\n    long millis = period;\n    timer = new Timer(\"Timer for '\"+ prefix +\"' metrics system\", true);\n    timer.scheduleAtFixedRate(new TimerTask() {\n          @Override\n          public void run() {\n            try {\n              onTimerEvent();\n            } catch (Exception e) {","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/impl/MetricsSystemImpl.java#L337-L373","documentation":"MetricsSystemImpl.currentConfig() copies the active metrics2 configuration into a PropertiesConfiguration and writes it to a StringWriter to produce a string dump. Any failure during the write is wrapped in MetricsConfigException('Error stringify config', e) with the original cause attached, so the in-memory config could not be serialized.","triggerScenarios":"Calling currentConfig() (directly or via tooling that dumps metrics config) when the loaded configuration holds values PropertiesConfiguration cannot render — e.g., non-scalar objects injected programmatically by custom metrics plugins — or when the writer itself throws.","commonSituations":"Custom MetricsSystem configuration assembled in code rather than from hadoop-metrics2.properties; plugins that mutate the config object; typically noticed when dumping config for debugging.","solutions":["Inspect MetricsConfigException.getCause() to see exactly what PropertiesConfiguration failed on","Audit hadoop-metrics2.properties and any programmatic config for non-string property values","Simplify the offending property to a plain string value or remove it"],"exampleFix":"// before\nString dump = ((MetricsSystemImpl) ms).currentConfig();  // throws MetricsConfigException\n\n// after\ntry {\n  String dump = ((MetricsSystemImpl) ms).currentConfig();\n} catch (MetricsConfigException e) {\n  LOG.error(\"Cannot stringify metrics config: \" + e.getCause(), e);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  String cfg = metricsSystem.currentConfig();\n} catch (MetricsConfigException e) {\n  LOG.error(\"metrics config dump failed: \" + e.getCause(), e);\n  // proceed without the dump; do not fail the application for a diagnostics call\n}","preventionTips":["Keep metrics2 configuration values as plain strings","Treat currentConfig() as a diagnostics helper: wrap and log, never let it gate startup","Log the wrapped cause (e.getCause()) — it names the property that failed serialization"],"tags":["metrics2","hadoop","configuration","serialization"],"backgroundTag":"config-serialization-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}