# TLS SANs not applied to Logstash custom service certificate in ECK

**URL:** <https://discuss.elastic.co/t/tls-sans-not-applied-to-logstash-custom-service-certificate-in-eck/384148>\
**Category:** Elastic Cloud on Kubernetes (ECK)\
**Created:** [December 17, 2025, 1:38pm UTC](https://discuss.elastic.co/t/tls-sans-not-applied-to-logstash-custom-service-certificate-in-eck/384148 "2025-12-17T13:38:25Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![CitizenSteak](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/32.png) [@CitizenSteak](https://discuss.elastic.co/u/CitizenSteak)\
**Post date:** [December 17, 2025, 1:38pm UTC](https://discuss.elastic.co/t/tls-sans-not-applied-to-logstash-custom-service-certificate-in-eck/384148/1 "2025-12-17T13:38:25Z")

</div>

# Context

I have filebeat installed on a VM and I’m trying to send logs to a logstash instance deployed on a K3S cluster.

# Description of the issue

When configuring a custom Logstash service with `selfSignedCertificate` and `subjectAltNames` in ECK, the generated certificate does not include the specified SANs. This causes TLS handshake failures when clients (e.g., Filebeat) validate the certificate against the hostname used for connection.

I’m using the eck-stack Helm Chart. Here’s the snippet for eck-logstash :

```yaml
eck-logstash:
  enabled: true
  fullnameOverride: logstash

  count: 1
  elasticsearchRefs:
    - clusterName: elasticsearch-es
      name: elasticsearch
  monitoring:
    metrics:
      elasticsearchRefs:
      - name: elasticsearch
    logs:
      elasticsearchRefs:
      - name: elasticsearch
  config:
    pipeline.workers: 4
    log.level: debug
  pipelines:
    - pipeline.id: main
      config.string: |
        [...]
  services:
    - name: filebeat-to-logstash
      service:
        spec:
          type: LoadBalancer
          ports:
          - port: 5044
            targetPort: 5044
            name: "filebeat-to-logstash"
            protocol: TCP
  http:
    service:
      spec:
        type: LoadBalancer
    tls:
      selfSignedCertificate:
        subjectAltNames:
        - dns: logstash-vm.example.com
  podTemplate:
    spec:
      ports:
        - containerPort: 5044
          name: filebeat-to-logstash

```

I did this according to the documentation and it works for Fleet Server but Logstash does not take it into account.

> **[Reserve static IP and custom domain - Manage HTTP certificates on ECK | Elastic...](https://www.elastic.co/docs/deploy-manage/security/k8s-https-settings#k8s-static-ip-custom-domain)**
>
> ECK offers several options for securing the HTTP endpoints of Elasticsearch and Kibana. By default, the operator generates a dedicated CA per deployment,...

The particularity is that I had to create a custom LoadBalancer service in order to expose the port that will be used by my beats (5044) because only the api (9600) has a service created by Operator by default.

**Is this supported by the Chart ? Am I doing it the wrong way ?**  
Initially, I wanted to open an issue on Github but I’m not sure how to categorize it, so I’m posting it here first.

# Steps to reproduce :

Deploy Logstash with ECK using the provided configuration.

1. Check the certificate exposed on port 5044 using:

2. Observe that the certificate does not include the SAN `logstash-vm.example.com`

3. Filebeat fails to connect with the error:

```bash
x509: certificate is valid for logstash-ls-http.collog.ls.local, logstash-ls-http, logstash-ls-api.collog.svc, logstash-ls-api.collog, not logstash-vm.example.com

```

---

<div class="post-metadata">

**Author:** ![pebrc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/pebrc/32/101790_2.png) [@pebrc](https://discuss.elastic.co/u/pebrc)\
**Post date:** [December 31, 2025, 3:12pm UTC](https://discuss.elastic.co/t/tls-sans-not-applied-to-logstash-custom-service-certificate-in-eck/384148/2 "2025-12-31T15:12:49Z")

</div>

Your configuration uses `http.tls.selfSignedCertificate.subjectAltNames`, but **the Logstash CRD does not have an `http` field** like Elasticsearch and Kibana do. This configuration is being silently ignored.

Looking at the Logstash API types:

```auto
type LogstashService struct {
	Name string `json:"name,omitempty"`
	// Service defines the template for the associated Kubernetes Service object.
	Service commonv1.ServiceTemplate `json:"service,omitempty"`
	// TLS defines options for configuring TLS for HTTP.
	TLS commonv1.TLSOptions `json:"tls,omitempty"`
}

```

### Why This Happens

ECK only generates certificates for the **API service** (port 9600), not for custom services like the beats input (port 5044). Looking at the controller code:

```auto
	_, results = certificates.Reconciler{
		K8sClient: params.Client,
		DynamicWatches: params.Watches,
		Owner: &params.Logstash,
		TLSOptions: apiSvcTLS,
		Namer: logstashv1alpha1.Namer,
		Metadata: params.Meta,
		Services: []corev1.Service{apiSvc}, // Only API service!
		GlobalCA: params.OperatorParams.GlobalCA,
		CACertRotation: params.OperatorParams.CACertRotation,
		CertRotation: params.OperatorParams.CertRotation,
		GarbageCollectSecrets: true,
	}.ReconcileCAAndHTTPCerts(params.Context)

```

The certificate reconciler **only includes the API service** , so custom input services don't get certificates with the specified SANs.

### Current Workarounds

**Option 1: Use the existing ECK-generated certificate with Filebeat's `ssl.verification_mode`**

If you can accept certificate verification without hostname checking:

```yaml
# In Filebeat configuration
output.logstash:
  hosts: ["logstash-vm.example.com:5044"]
  ssl.enabled: true
  ssl.verification_mode: certificate # Verifies CA but not hostname
  ssl.certificate_authorities: ["/path/to/ca.crt"]

```

**Option 2: Use cert-manager to generate certificates**

Create certificates externally with the correct SANs and mount them into the Logstash pod:

```yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: logstash-beats-cert
spec:
  secretName: logstash-beats-tls
  issuerRef:
    name: your-issuer
    kind: ClusterIssuer
  dnsNames:
    - logstash-vm.example.com
  # ... rest of cert config

```

Then configure the Logstash pipeline to use these certificates:

```yaml
input {
  beats {
    port => 5044
    ssl_enabled => true
    ssl_certificate => "/path/to/tls.crt"
    ssl_key => "/path/to/tls.key"
  }
}

```

**Option 3: Disable TLS on the beats input (not recommended for production)**

If this is for development/testing only:

```yaml
input {
  beats {
    port => 5044
    ssl_enabled => false
  }
}

```

**Option 4: Expose Logstash through Ingress/Gateway**

You could use an Ingress for TLS termination and use dedicated non-self-signed certificates for that, but there are some gotchas as the Beats input is not HTTP but TCP (lumberjack protocol). So you would have to use a vendor specific feature e.g. tcp-routing in the Nginx controller. Or you use the newer Gateway API that has good support for TCP routes:

```yaml
---
# Gateway with a listener for beats traffic
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: logstash-gateway
spec:
  gatewayClassName: nginx # or istio, envoy, cilium, etc.
  listeners:
    - name: beats
      port: 5044
      protocol: TLS
      hostname: logstash-external.example.com
      tls:
        mode: Terminate
        certificateRefs:
          - name: logstash-external-cert # Secret with correct SANs
            kind: Secret
      allowedRoutes:
        kinds:
          - kind: TCPRoute

---
# TCPRoute to forward traffic to Logstash
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
  name: logstash-beats-route
spec:
  parentRefs:
    - name: logstash-gateway
      sectionName: beats
  rules:
    - backendRefs:
        - name: logstash-ls-beats # Logstash service
          port: 5044

---
# Certificate with correct SANs (e.g., from cert-manager)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: logstash-external-cert
spec:
  secretName: logstash-external-cert
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - logstash-external.example.com

```

### Is This a Bug or Missing Feature?

This is a **feature gap** rather than a bug. The documentation for `selfSignedCertificate.subjectAltNames` applies to Elasticsearch and Kibana's `http` configuration, but Logstash has a different architecture with its `services` array. I have raised [Support TLS certificate generation with custom SANs for Logstash custom services (e.g., beats input) · Issue #8981 · elastic/cloud-on-k8s · GitHub](https://github.com/elastic/cloud-on-k8s/issues/8981) to address it. I assume that most production setups use dedicated, proper certificates and or seperate TLS termination, which is why we haven't had any requests for this yet.
