{"record":{"id":"407387e651001ec5","repo":"apache/hadoop","slug":"error-closing-connection-to-graphite-407387","errorCode":null,"errorMessage":"Error closing connection to Graphite.","messagePattern":"Error closing connection to Graphite\\.","errorType":"exception","errorClass":"MetricsException","httpStatus":null,"severity":"warning","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/sink/GraphiteSink.java","lineNumber":119,"sourceCode":"      LOG.warn(\"Error sending metrics to Graphite.\", e);\n      try {\n        graphite.close();\n      } catch (Exception e1) {\n        throw new MetricsException(\"Error closing connection to Graphite\", e1);\n      }\n    }\n  }\n\n  @Override\n  public void flush() {\n    try {\n      graphite.flush();\n    } catch (Exception e) {\n      LOG.warn(\"Error flushing metrics to Graphite.\", e);\n      try {\n        graphite.close();\n      } catch (Exception e1) {\n        throw new MetricsException(\"Error closing connection to Graphite.\", e1);\n      }\n    }\n  }\n\n  @Override\n  public void close() throws IOException {\n    graphite.close();\n  }\n\n  public static class Graphite {\n    private final static int MAX_CONNECTION_FAILURES = 5;\n\n    private String serverHost;\n    private int serverPort;\n    private Writer writer = null;\n    private Socket socket = null;\n    private int connectionFailures = 0;\n","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/sink/GraphiteSink.java#L101-L137","documentation":"GraphiteSink.flush() calls graphite.flush() every flush cycle. If the flush throws (broken connection), the sink logs WARN \"Error flushing metrics to Graphite.\" and attempts graphite.close(); when the close also throws, MetricsException(\"Error closing connection to Graphite.\", e1) is thrown. As with the putMetrics variant, the surfaced exception is the secondary close failure and the root network error is in the preceding WARN log.","triggerScenarios":"flush() on a socket already broken by a Graphite restart, connection reset, or idle-timeout firewall drop; the subsequent close() on the dead socket throws as well.","commonSituations":"Graphite server restarts; LB/NAT idle timeouts shorter than the sink flush interval; network partitions that leave the TCP connection half-open.","solutions":["Check the WARN 'Error flushing metrics to Graphite.' line for the underlying exception","Restore Graphite server availability and verify server_host/server_port connectivity (nc -vz host port)","Rely on lazy reconnection: the next putMetrics/write cycle re-establishes the socket","Restart the daemon after remediation if the sink has hit its 5-failure silent-give-up limit"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"try (Socket s = new Socket()) {\n  s.connect(new InetSocketAddress(graphiteHost, graphitePort), 3000);\n} catch (IOException e) {\n  LOG.warn(\"Graphite endpoint unhealthy before flush: {}\", e.toString());\n}","typeGuard":null,"tryCatchPattern":"try {\n  sink.flush();\n} catch (MetricsException e) {\n  // flush + close both failed; connection is dead but the next write() reconnects\n  LOG.warn(\"Graphite flush/close failed; socket will be re-established on next write\", e);\n}","preventionTips":["Schedule Graphite restarts/maintenance with awareness that in-flight sink cycles will log one WARN + one exception each","Verify endpoint health (nc -vz) after any Graphite migration before assuming the sink recovered","Watch the failure count: after 5 consecutive failures the sink silently drops metrics until restart"],"tags":["graphite","metrics2","network","socket","flush"],"backgroundTag":"socket-write-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}