Splunk OpenTelemetry Collector (splunk-otel-collector-agent) causing Openshift control plane issues and cluster inaccessibility.
Splunk OTel Collector has been functioning for about a year. Now, OpenShift Kubernetes cluster master servers have been in an unhealthy state, causing their Kubernetes cluster to be inaccessible. It seems splunk-otel-collector-agent (otelcol) processes running on the control plane/master servers are holding log files ope (some are very large (1GB+)) that would normally be closed and deleted.
Capture the following information for investigation into this issue:
splunk-otel-collector --version
kubectl describe pod splunk-otel-collector-agent-xxxxx -n <namespace>
kubectl get pods -o wide -n <namespace>
kubectl logs <pod_name> -n splunk > splunk-otel-collector-agent.log
Cluster receiver logs (select the splunk pod name that contains "k8s-cluster-receiver" in the name):
kubectl logs <pod_name> -n splunk > splunk-otel-collector-k8s-cluster-receiver.log
helm show values splunk-otel-collector-chart/splunk-otel-collector > values.yaml
my-configmap in the command below with the actual name of your configmap, do this for both the Cluster Receiver and Agent Collector):filekubectl get configmap my-configmap -o yaml > my-configmap.yaml
or from Linux (capture the configmap.yaml file from this path):
cp /etc/otel/collector/configmap.yaml > configmap.yaml
Log file findings:
splunk-otel-collector-k8s-cluster-receiver.log shows failures to scrape the Prometheus endpoint due to high memory utilization. Ingestion stops until memory falls back down.2025-07-31T11:28:50.349Z error scrape/scrape.go:1298 Scrape commit failed {"kind": "receiver", "name": "prometheus/k8s_cluster_receiver", "data_type": "metrics", "scrape_pool": "otel-k8s-cluster-receiver", "target": "http://XXXXXXXXXXXXX:8889/metrics", "error": "data refused due to high memory usage"} github.com/prometheus/prometheus/scrape.(*scrapeLoop).scrapeAndReport.func1 github.com/prometheus/prometheus@v0.54.1/scrape/scrape.go:1298 github.com/prometheus/prometheus/scrape.(*scrapeLoop).scrapeAndReport github.com/prometheus/prometheus@v0.54.1/scrape/scrape.go:1376 github.com/prometheus/prometheus/scrape.(*scrapeLoop).run github.com/prometheus/prometheus@v0.54.1/scrape/scrape.go:1253
2025-07-31T11:28:50.250Z warn internal/transaction.go:129 Failed to scrape Prometheus endpoint {"kind": "receiver", "name": "prometheus/k8s_cluster_receiver", "data_type": "metrics", "scrape_timestamp": 1753961330249, "target_labels": "{__name__=\"up\", instance=\"XXXXXXXXXXXXX:8889\", job=\"otel-k8s-cluster-receiver\"}"} github.com/prometheus/prometheus@v0.54.1/scrape/scrape.go:1376 github.com/prometheus/prometheus/scrape.(*scrapeLoop).run github.com/prometheus/prometheus@v0.54.1/scrape/scrape.go:1253
2025-07-30T16:07:01.291Z info memorylimiter@v0.117.0/memorylimiter.go:196 Memory usage back within limits. Resuming normal operation. {"kind": "processor", "name": "memory_limiter", "pipeline": "metrics/collector", "cur_mem_mib": 484} 2025-07-30T16:07:10.165Z info internal/retry_sender.go:126 Exporting failed. Will retry the request after interval. {"kind": "exporter", "data_type": "metrics", "name": "splunk_hec/platform_metrics", "error": "Post \"https://XXXXXXXXXXXXXXX:8088/services/collector\": EOF", "interval": "35.570898833s"}
splunk-otel-collector-agent.log reports HTTP 400 messages which appear to begin at the 10 second interval marker, then 3 or 4 times in 1-2 second intervals, stop again, and pick up once more at the 10 second mark:2025-07-31T11:28:50.917Z error internal/queue_sender.go:103 Exporting failed. Dropping data. {"kind": "exporter", "data_type": "metrics", "name": "splunk_hec/platform_metrics", "error": "not retryable error: Permanent error: \"HTTP/1.1 400 Bad Request\\r\\nContent-Length: 60\\r\\nConnection: Keep-Alive\\r\\nContent-Type: application/json; charset=UTF-8\\r\\nDate: Thu, 31 Jul 2025 11:28:50 GMT\\r\\nServer: Splunkd\\r\\nVary: Authorization\\r\\nX-Content-Type-Options: nosniff\\r\\nX-Frame-Options: SAMEORIGIN\\r\\n\\r\\n{\\\"text\\\":\\\"Incorrect index\\\",\\\"code\\\":7,\\\"invalid-event-number\\\":1}\"", "dropped_items": 14} go.opentelemetry.io/collector/exporter/exporterhelper/internal.NewQueueSender.func1 go.opentelemetry.io/collector/exporter@v0.117.0/exporterhelper/internal/queue_sender.go:103 go.opentelemetry.io/collector/exporter/internal/queue.(*Consumers[...]).Start.func1 go.opentelemetry.io/collector/exporter@v0.117.0/internal/queue/consumers.go:43
Findings:
The core issue in this case is that an index either does not exist in Splunk or is named differently in the otel configuration than it is on the Splunk indexers, so data is not getting ingested. If the collector cannot successfully offload the data it has collected, its internal buffers (even if persistent queue is enabled) will eventually fill, leading to backpressure that propagates back to the receivers, causing them to hold onto files or drop data. The fact that this happens at 10-second intervals (matching Prometheus scrape intervals) suggests that every attempt to send a batch of metrics is failing due to this misconfiguration.
With Splunk OTel Collector agents configured to use an in-memory queue for log export while also tailing a large volume of log files on the master nodes, when the export pipeline experiences backpressure, the collector holds onto file handles to prevent data loss, which in turn prevents the operating system from truly deleting rotated log files, leading to disk space exhaustion. The frequent restarts occur due to memory pressure from the accumulating in-memory data.
Here's a breakdown of the findings:
The splunk_hec/platform_metrics exporter is sending metrics to an index that either doesn't exist, is misspelled, or the HEC token used does not have permissions to write to that index.
In-memory sending queue and backpressure:
values.yaml configuration for the Splunk OTel Collector explicitly shows splunkPlatform.persistentQueue.enabled: false. This means that the collector's sending queue, which buffers data before exporting it to the Splunk HEC endpoint, is configured to operate in-memory.filelog receiver uses file_storage for its internal checkpoints (to track its position in the log files) in /var/addon/splunk/otel_pos. This is distinct from the exporter's sending queue.File handle retention and disk space exhaustion:
filelog receiver will stop reading new data from the log files. Crucially, it keeps the file handles open to these log files so that it can resume reading from the last known position once the backpressure is relieved.logrotate for system logs) attempt to rotate and delete old log files. Because otelcol still holds open file handles to these "deleted" files, the operating system cannot truly free up the disk space occupied by them. The files are marked for deletion but remain on disk until all open handles are released. With the files open, they cannot be deleted from the node until closed, filling up the disk space until then. This explains why the disk usage increases despite logs being "rotated."High restart counts and OOMKills:
kubectl get pods output will show many splunk-otel-collector-agent pods with high restart counts.kubectl describe pod output and values.yaml will show the otel-collector container's memory limit. (for example, 500Mi).splunk-otel-collector-k8s-cluster-receiver.log explicitly state that the Prometheus receiver within the cluster receiver pod is unable to process scraped metrics because the collector itself is experiencing high memory usage. The memory_limiter processor (configured in both the cluster receiver configmap.yaml and collector agent configmap.yaml files) is actively dropping or refusing data due to memory constraints.Implementing these changes should resolve the immediate backpressure issue and protect against future data loss by allowing the collector to buffer logs to disk during periods of backpressure, enabling it to release file handles to rotated logs more promptly and prevent disk space exhaustion.
splunk-otel-collector-agent is causing disk space exhaustion and high resource usage on master nodes, it directly jeopardizes the cluster's core functionality. Isolating the control plane from this workload is paramount.splunk-otel-collector-agent from scheduling on master nodes, thereby stopping the log file handle issue and disk space exhaustion on those critical servers.values.yaml), locate the tolerations section under the top-level tolerations (this applies to the agent DaemonSet) and remove or comment out the entries that allow scheduling on master/control plane nodes:tolerations:
# - key: node-role.kubernetes.io/master # Remove or comment this line
# effect: NoSchedule
# operator: Exists
# - key: node-role.kubernetes.io/control-plane # Remove or comment this line
# effect: NoSchedule
# operator: Exists
# ... keep other necessary tolerations if applicable to other node types you want to monitor
Important Considerations if you remove tolerations:
Loss of Control Plane Observability: By preventing the agent from running on master nodes, you will lose direct collection of host-level metrics, container logs, and system logs from those specific nodes. This creates a monitoring blind spot for your control plane components.
Underlying Issues Remain: Removing tolerations addresses the _symptom_ on master nodes, but it does not fix the underlying problems (memory pressure, HEC configuration errors, certificate issues). These problems will continue to affect the splunk-otel-collector-agent pods running on your worker nodes.
splunk_hec/platform_metrics. Verify the affected index exists in Splunk and the HEC token has the necessary write permissions to it. This will allow data to actually be accepted by Splunk.splunkPlatform.persistentQueue.enabled: true in your values.yaml and increase the agent's memory limits (e.g., to 1Gi or more) to provide robust buffering and prevent in-memory queue overflows.
values.yaml to enable the persistent queue for splunkPlatform:"
splunkPlatform:
# ... other configurations ...
sendingQueue:
enabled: true
numConsumers: 10
queueSize: 1000 # This queue will now be persistent
persistentQueue:
enabled: true
storagePath: "/var/addon/splunk/exporter_queue" # This path is already mounted to the agent
agent.resources.limits.memory to at least 1Gi (or more, depending on your log volume) to accommodate the additional overhead of the disk-based storage.storagePath (ex: /var/addon/splunk/exporter_queue). If this directory starts to grow uncontrollably, it means your export pipeline is still not keeping up with the ingestion rate, and further investigation into Splunk HEC capacity or network throughput is required.Here are documentation links that support the findings and recommendations discussed:
persistentQueue option and its implications, including the recommendation to increase memory limits.memory_limiter processor works, including its role in preventing out-of-memory conditions by dropping data or pausing pipelines.filelog receiver tails files, manages state, and uses storage for checkpoints. Understanding its operation helps explain why file handles are held.| Revision | Publish Date | Comments |
|---|---|---|
1.0 |
01-Oct-2026
|
Initial Release |