Skip to content

helm: stale TLS blocks in ingresses cause ssl-redirect loops and break websockets #102

@mosoriob

Description

@mosoriob

Problem

When upgrading the mint Helm release, ingresses can retain stale spec.tls entries from previous deploys even when the current chart values set tls: []. Helm's 3-way merge does not remove fields that were added by a prior release but are absent from the current manifest.

Because nginx-ingress enables ssl-redirect by default on any ingress that contains a TLS block — regardless of whether the request host is listed in that block — all hosts on the affected ingress get a 308 redirect to HTTPS, and the backing self-signed cert causes browsers to fail.

Symptoms

  • curl -I http://mint.local returns 308 Permanent Redirect to https://mint.local
  • Chrome shows ERR_CERT_AUTHORITY_INVALID and HSTS makes it sticky
  • UI websocket fails: WebSocket connection to 'ws://graphql.mint.local/v1/graphql' failed
  • kubectl get ingress -n mint shows stale TLS hosts (e.g. mint.tacc.utexas.edu, graphql.mint.tacc.utexas.edu) on local-only installs

Reproduction

  1. Install mint chart once with TLS values for a production host
  2. Redeploy with a values file that does not set tls (e.g. a local dynamo-values.yaml)
  3. Observe: live ingress still has spec.tls and redirects HTTP to HTTPS

Proposed fixes

Any of these would prevent the issue; ideally combine (1) and (2):

  1. Set ssl-redirect: false by default in the chart for local/dev scenarios, or make it configurable per ingress component:

    components:
      ui:
        ingress:
          annotations:
            nginx.ingress.kubernetes.io/ssl-redirect: "false"
  2. Always render the tls: key in ingress templates, even when empty, so Helm's merge correctly removes stale entries. Current template uses {{- if .Values.components.ui.ingress.tls }}, which omits the field entirely and leaves stale data intact.

  3. Document the upgrade gotcha in the chart README with a one-liner to clean up:

    for ing in $(kubectl get ingress -n mint -o name); do
      kubectl patch $ing -n mint --type=json -p='[{"op":"remove","path":"/spec/tls"}]' 2>/dev/null
    done
  4. Add a global.tls.enabled switch so local installs can disable TLS wiring across all ingresses at once.

Affected templates

  • charts/mint/templates/ingress-ui.yaml
  • charts/mint/templates/ingress-hasura.yaml
  • charts/mint/templates/ingress-ensemble-manager.yaml
  • charts/mint/templates/ingress-data-catalog.yaml
  • charts/mint/templates/ingress-model-catalog*.yaml
  • (all ingress templates use the same {{- if ... .tls }} pattern)

Workaround (current)

Manually patch stale ingresses after upgrade:

kubectl patch ingress mint-ui -n mint --type=json -p='[{"op":"remove","path":"/spec/tls"}]'
kubectl patch ingress mint-hasura -n mint --type=json -p='[{"op":"remove","path":"/spec/tls"}]'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions