{"record":{"id":"364a8dac794c5c0a","repo":"SonarSource/sonarqube","slug":"node-has-critically-low-disk-space-free","errorCode":null,"errorMessage":"Node [{}] has critically low disk space: {}% free ({} bytes available out of {} bytes total)","messagePattern":"Node \\[(.+?)\\] has critically low disk space: (.+?)% free \\((.+?) bytes available out of (.+?) bytes total\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ElasticSearchMetricTask.java","lineNumber":171,"sourceCode":"  private double updateAndGetMaxDiskUsagePercent(@Nullable NodeStatsResponse nodeStatsResponse, double thresholdPercent) {\n    try {\n      if (nodeStatsResponse == null || nodeStatsResponse.getNodeStats().isEmpty()) {\n        return 0.0;\n      }\n\n      double maxDiskUsagePercent = 0.0;\n\n      for (NodeStats nodeStat : nodeStatsResponse.getNodeStats()) {\n        final long availableBytes = nodeStat.getDiskAvailableBytes();\n        final long totalBytes = nodeStat.getDiskTotalBytes();\n\n        if (totalBytes > 0) {\n          final double freePercent = (availableBytes * 100.0) / totalBytes;\n          final double usedPercent = 100.0 - freePercent;\n          maxDiskUsagePercent = Math.max(maxDiskUsagePercent, usedPercent);\n\n          if (freePercent < thresholdPercent) {\n            LOG.warn(\"Node [{}] has critically low disk space: {}% free ({} bytes available out of {} bytes total)\",\n              nodeStat.getName(), String.format(Locale.ROOT, \"%.2f\", freePercent), availableBytes, totalBytes);\n          }\n        }\n      }\n\n      // Update metric for observability\n      serverMonitoringMetrics.setElasticSearchDiskUsagePercent(maxDiskUsagePercent);\n\n      return maxDiskUsagePercent;\n    } catch (Exception e) {\n      LOG.error(\"Failed to check disk space\", e);\n      // Return 0.0 on error to avoid false positives\n      return 0.0;\n    }\n  }\n\n  @Override\n  public long getDelay() {","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ElasticSearchMetricTask.java#L153-L189","documentation":"ElasticSearchMetricTask polls ES cluster node stats and records max disk usage as a metric. When a node's free disk percentage falls below the configured threshold, it logs this warning identifying the node, free percent, and byte counts.","triggerScenarios":"A scheduled ES monitoring task run finds a node stat whose freePercent < thresholdPercent while totalBytes > 0 in updateAndGetMaxDiskUsagePercent.","commonSituations":"Elasticsearch data nodes filling up with indexes; too-small disks after index growth; missing ILM/retention policies causing unbounded index accumulation.","solutions":["Free disk space on the reported Elasticsearch node (delete old indexes, snapshot and prune)","Verify the low-disk threshold configuration matches operational expectations","Add or fix index lifecycle/retention policies so disk usage does not trend to the threshold","Scale the node's disk or add nodes to the ES cluster"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (freePercent < thresholdPercent) { provisionMoreDisk(node); }","typeGuard":"boolean hasUsableStat(NodeStat s) { return s != null && s.getTotalBytes() > 0; }","tryCatchPattern":null,"preventionTips":["Monitor ES node disk trends and alert before the threshold","Configure index retention/ILM to prevent unbounded growth","Provision headroom (e.g. keep disk usage below 80%)"],"tags":["elasticsearch","disk-space","monitoring"],"backgroundTag":"resource-not-found","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}