Skip to main content
emnode
Compliance Medium severity

AWS Security Hub · ES

ES.4: ES error logging to CW should be enabled

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub ES.4 check?

ES.4 checks that a domain publishes error logs to CloudWatch Logs and fails when it does not. Error logging captures the WARN, ERROR, and FATAL lines OpenSearch emits, plus exceptions like MapperParsingException and SearchPhaseExecutionException; all log types are off by default.

Why does ES.4 matter?

Because there's no bill attached, this finding has no natural pressure to get closed; it just sits as a Medium while the domain fails silently. Error logs are the difference between knowing why a query failed at 2 a.m. and guessing, and they form part of how you reconstruct what a system did under attack. The control maps to NIST 800-53 AU-2, AU-3, and AU-12.

How do I fix ES.4?

  1. Create or choose a CloudWatch Logs group for the domain's error logs.
  2. Grant the domain a resource policy allowing it to write to that log group.
  3. Enable error-log publishing in the domain's logging options.
  4. Set a retention policy on the log group and alert on FATAL/ERROR spikes.

Remediation script · bash

# Enable the EKS audit log type (non-disruptive), then bound the cost with retention.
aws eks update-cluster-config \
  --name prod-platform \
  --logging '{"clusterLogging":[{"types":["audit"],"enabled":true}]}'

aws logs put-retention-policy \
  --log-group-name /aws/eks/prod-platform/cluster \
  --retention-in-days 90

# Turn on GuardDuty EKS Audit Log Monitoring and auto-enable for the whole org.
DETECTOR=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
aws guardduty update-detector --detector-id "$DETECTOR" \
  --features '[{"Name":"EKS_AUDIT_LOGS","Status":"ENABLED"}]'
aws guardduty update-organization-configuration --detector-id "$DETECTOR" \
  --features '[{"Name":"EKS_AUDIT_LOGS","AutoEnable":"ALL"}]'

Full walkthrough (console steps, edge cases and verification) in the lesson Enable cluster and search audit logging.

Is ES.4 a false positive?

The check only looks for error-log publishing to CloudWatch Logs (logtype 'error'), so a domain can fail while still being fully observable through another path, for instance a short-lived dev or proof-of-concept domain whose logs you tail directly, or a domain where you forward error output to a different sink and deliberately don't pay for a second copy in CloudWatch. The control can't see those alternatives; it just sees the publishing option switched off. For an ephemeral or genuinely non-production domain where CloudWatch error logging adds cost without adding coverage, record the decision and set the finding to SUPPRESSED naming the domain, rather than enabling a log stream you'll never read. Keep in mind the bar is low, so for anything load-bearing it's usually cheaper to just turn it on than to defend the exception.

Part of the learning path See what's happening
  • ES.1 ES domains should encrypt at rest
  • ES.2 A legacy Elasticsearch domain is publicly accessible
  • ES.3 ES should encrypt node-to-node traffic
  • ES.5 ES domains should have audit logging
  • ES.6 ES domains should have >= 3 data nodes
  • ES.7 ES domains should have >= 3 dedicated master nodes
  • ES.8 ES should use latest TLS policy