Why Does Ignition 8.3 Throw MissingGatewayAddressException?

Daniel Price11 min read
HMI / SCADAOther ManufacturerTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Where does the Perspective launch request fail?

In this setup, an Ignition 8.3 gateway runs HTTP-only on port 8088 inside a Kubernetes pod. An Nginx Ingress sits in front of it and terminates TLS. The gateway web UI works, and direct Perspective project URLs load. Only the session launcher at app/home/perspective/session-launcher fails, and it logs com.inductiveautomation.perspective.gateway.comm.Routes$MissingGatewayAddressException: null. The same failure appears on a Docker host with Traefik terminating TLS and forwarding plain HTTP to 8088.

Trace the request one hop at a time:

Hop Transport What happens to the request
1. Browser to Ingress/Traefik HTTPS, TCP 443 The proxy terminates TLS using the certificate held in the Ingress Secret or the Traefik store.
2. Proxy to Service/pod Plain HTTP, TCP 8088 The proxy adds forwarded headers such as X-Forwarded-Proto: https and X-Forwarded-Host.
3. Gateway Jetty stack HTTP inside the container RewriteHandler and HeaderPatternRule run, then GatewayFilter. With forwarded headers enabled, Jetty treats the request as secure even though the socket is plain HTTP.
4. Perspective data route In-process Routes.getRunnableProjects (Routes.java:1854) builds an absolute gateway URL for the launcher list and throws.

A direct project link works because the browser already holds a valid URL, and the session loads relative to it. The launcher is different. It has to produce an absolute gateway address (scheme, host, port) for every launchable project. That address comes from the gateway's own webserver settings, not from the URL in the browser.

Why does getRunnableProjects throw when the proxy terminates TLS?

The address resolution in the Perspective route follows this logic:

if (!req.getRequest().isSecure() && settings.httpPort().isPresent()) {
    gatewayAddress = new HttpURL("http", settings.address(), settings.httpPort().getAsInt(), null).toString();
} else if (settings.httpsPort().isPresent()) {
    gatewayAddress = new HttpURL("https", settings.address(), settings.httpsPort().getAsInt(), null).toString();
} else {
    throw new MissingGatewayAddressException();
}

The HTTP branch runs only when the request is not secure. gateway.useProxyForwardedHeader=true tells Jetty to trust X-Forwarded-Proto: https, so isSecure() returns true. That skips the HTTP branch even though a valid HTTP port exists. The code then needs an HTTPS port. If the gateway has no HTTPS configured, and no public HTTPS port resolves, it falls through to the exception.

Request seen as secure HTTP port resolved HTTPS port resolved Launcher result
No Yes Any
Yes Any Yes
No No Yes
Yes Any No MissingGatewayAddressException

This mixed negotiation is the whole fault. The client-side leg is HTTPS, the backend leg is HTTP, and the forwarded header reports the client-side scheme. The gateway then needs an HTTPS address that it does not own. Gateways on 8.1 (8.1.48 in this case) ran with the same proxy and forwarded-header settings without this error, so the failure is new in the 8.3 launcher route.

Which gateway settings and versions trigger it?

Two tracked defects produce the same exception. They differ in how the public address is configured.

Ticket Trigger condition Versions observed Status
IGN-13832 Public address settings defined. The gateway has no HTTPS. The request arrives as secure through forwarded headers, and the secure port fails to resolve. 8.3.0 pre-release builds Fixed in 8.3.0-beta4 and the 8.3.0 final release. Rechecked on 8.3.1 with a TLS-terminating ingress forwarding to http/8088.
IGN-15058 Auto Detect HTTP Address enabled behind a TLS-terminating reverse proxy, with Use Proxy Forwarded Headers on. Reported on 8.3.1 and 8.3.7 Unresolved at last report. The workaround is to set the public address manually.

On an 8.3.1 cloud deployment with auto-detect on, the following toggle combinations were observed:

Use Proxy Forwarded Headers Force Secure Redirect Launcher Side effect
On On Error (baseline) None
On Off Error None
Off Off Projects listed The IdP SSO configuration breaks, because it needs forwarded headers.

Force Secure Redirect has no effect on the fault. The forwarded-header flag decides whether the request looks secure. Auto-detect decides whether a usable HTTPS port exists for the second branch. Once auto-detect was turned off and the public address plus HTTP and HTTPS ports were entered by hand, the launcher listed the projects with forwarded headers still on.

How do the available fixes compare?

Approach Clears IGN-13832 path Clears IGN-15058 path Keeps forwarded headers (SSO) Operational cost
Run 8.3.0 final or later Yes No Yes Image tag change and restart
Disable Auto Detect HTTP Address; set Public Address, HTTP Port, HTTPS Port Yes (on a fixed build) Yes Yes Three values per gateway, kept in the deployment manifest
Enable TLS on the gateway webserver Yes (confirmed working) Not tested Yes Certificate conversion, renewal sync, backend re-encryption
Disable Use Proxy Forwarded Headers Yes Yes (observed) No Breaks IdP SSO; gateway sees the internal scheme and host
Inductive Automation Helm chart Yes Yes Yes Adopting the chart; public address config is set by default

Enabling TLS on the gateway works because it puts an HTTPS port into settings.httpsPort(), which satisfies the second branch. It still adds encryption on a backend leg that the proxy already protects, and it was never required once IGN-13832 was fixed. Disabling forwarded headers is not an option when an identity provider validates redirect URIs against the external HTTPS hostname.

Which configuration should a TLS-offloaded 8.3 gateway run?

Use this combination for any 8.3 gateway behind Nginx Ingress, Traefik, or a similar TLS-terminating proxy:

  • An 8.3.0 final or later image. This removes IGN-13832.
  • Auto Detect HTTP Address disabled. This avoids IGN-15058 on every 8.3 build reported so far, including 8.3.7.
  • Public Address set to the external hostname clients type. Public HTTP Port and Public HTTPS Port set to the ports exposed on the proxy, typically 80 and 443.
  • gateway.useProxyForwardedHeader=true, so SSO, redirects, and client-facing URLs reflect the external scheme and host.
  • Optionally gateway.forceSecureRedirect=true to push plain-HTTP visitors to HTTPS.
  • The backend leg stays plain HTTP to 8088.

The public ports must match what the client sees at the proxy. Do not use the container ports. With -h 8088 -s 8043, the launcher builds , and that port is not reachable from outside the cluster. The launcher list renders without error, but every launch link fails.

How do you set the public address in a Kubernetes manifest?

The image accepts three runtime options for public address settings. You must supply all three:

Option Sets Example
-a Public Address (hostname) ignition.k8s.localtest.me
-h Public HTTP Port 80
-s Public HTTPS Port 443

Gateway arguments such as gateway.useProxyForwardedHeader=true go after a -- separator in the container arguments.

  1. Confirm the Ingress host rule and the TLS Secret hostname match the value you will pass to -a.
  2. Confirm the Ingress backend targets the gateway Service on HTTP 8088, not 8043.
  3. Add the public address options and gateway arguments to the container args:
    containers:
      - name: ignition
        image: <ignition-8.3.0-final-or-later-image>
        ports:
          - containerPort: 8088
        args:
          - "-a"
          - "ignition.k8s.localtest.me"
          - "-h"
          - "80"
          - "-s"
          - "443"
          - "--"
          - "gateway.useProxyForwardedHeader=true"
          - "gateway.forceSecureRedirect=true"
  4. Roll the Deployment or StatefulSet so the pod restarts with the new arguments.
  5. Open the Gateway Webserver config page and confirm that Auto Detect HTTP Address is off and that the three public values match the manifest.

If you deploy with the Inductive Automation Helm chart, it sets the public address configuration by default. Check the rendered values rather than adding the options by hand.

How do you apply the same fix on Docker with Traefik or through the web UI?

On a Docker host with Traefik terminating TLS, the data path is the same: HTTPS at Traefik, HTTP 8088 to the container. Apply the same fix. Traefik certificates stay in Traefik, and Ignition needs no certificate.

services:
  ignition:
    image: <ignition-8.3.0-final-or-later-image>
    command: >
      -a scada.example.com
      -h 80
      -s 443
      --
      gateway.useProxyForwardedHeader=true
      gateway.forceSecureRedirect=true

To change a running gateway without redeploying:

  1. Open the Gateway Webserver config page.
  2. Uncheck Auto Detect HTTP Address.
  3. Enter the external hostname in Public Address, 80 in HTTP Port, and 443 in HTTPS Port. Use different values only if the proxy listens on other ports.
  4. Leave Use Proxy Forwarded Headers checked if SSO or another consumer depends on it.
  5. Save, then reload the session launcher.

Settings made in the UI can be overwritten if the container restarts with conflicting runtime options. In orchestrated deployments, keep the manifest as the source of truth. Older Compose files built for a non-official Ignition image sometimes set environment variables such as GATEWAY_PUBLIC_ADDRESS, GATEWAY_PUBLIC_HTTP_PORT, and GATEWAY_PUBLIC_HTTPS_PORT, along with gateway.resolveHostNames=false. When you migrate such a file to an 8.3 image, move the public address to -a/-h/-s. Also check that values like localhost with ports 9088/9043 are not carried forward. Those values produce launcher URLs that no remote client can reach.

How do you force HTTPS redirects when Ignition has no certificate?

Before the fix, the Force Secure Redirect setting could not be enabled when HTTPS was handled outside Ignition. As a result, a user who browsed to the http:// address was not redirected. From 8.3.0-beta4 onward, you can apply it without HTTPS configured in Ignition, but only through a gateway argument:

gateway.forceSecureRedirect=true

Pass it after the -- separator, alongside gateway.useProxyForwardedHeader=true. The gateway reads the forwarded scheme to decide whether a request is already secure, so the redirect only behaves correctly with forwarded headers enabled. Without them, every request from the proxy arrives as plain HTTP, and the gateway can redirect in a loop.

The alternative is to redirect at the proxy: a Traefik redirect middleware, or an HTTP-to-HTTPS redirect on the Nginx Ingress. Plain-HTTP requests then never reach the gateway. Use one location for the redirect, not both, so a misconfiguration surfaces in one place.

When is end-to-end TLS to the gateway worth the overhead?

Enabling TLS in the Gateway Web Settings cleared the launcher error on the Kubernetes deployment before the fixed build was available. Consider end-to-end TLS in these cases:

  • Policy requires encryption on the pod network or between the proxy and the gateway.
  • You are pinned to a pre-fix 8.3 build and cannot change public address settings.

The costs come from certificate handling. Ignition's webserver takes a PFX keystore. With ACME tooling (a Let's Encrypt companion container, step-ca, or Traefik's resolver), you need a script that converts the issued certificate and key into an ssl.pfx for Ignition, and you must re-run it on every renewal. If that job fails, the backend leg breaks while the proxy leg keeps serving.

In Kubernetes, the Inductive Automation Helm chart is designed to reuse the Secret already linked to the Ingress for the gateway webserver. That gives end-to-end encryption without a separate certificate pipeline. Point the Ingress backend at the HTTPS port and set the backend protocol on the Ingress accordingly.

How do you confirm the launcher resolves the correct gateway address?

  1. Check the gateway version on the status page. It must be 8.3.0 final or later. If it is earlier, change the image tag first.
  2. On the Gateway Webserver config page, confirm Auto Detect HTTP Address is unchecked and that Public Address, HTTP Port, and HTTPS Port show the external hostname, 80, and 443.
  3. Confirm the proxy forwards scheme and host. From a pod in the same namespace, or through a port-forward to 8088, the gateway should see requests arriving with X-Forwarded-Proto: https when clients connect on 443.
  4. Browse to https://<public-address>/app/home/perspective/session-launcher. The project list should render with no error banner.
  5. Open the browser developer tools Network tab and reload. The Perspective data request behind the launcher should return 200, not 500.
  6. Hover over or copy a launch link. It must read https://<public-address>:443 or the equivalent with the default port omitted. It must never show 8088, 8043, localhost, or a pod or Service name.
  7. Browse to the plain http:// address. If gateway.forceSecureRedirect=true or a proxy redirect is in place, confirm a single redirect to HTTPS with no loop.
  8. If SSO is configured, log in through the identity provider and confirm the callback returns to the HTTPS public hostname.
  9. Tail the gateway logs, then reload the launcher several times and restart the pod once. Confirm that MissingGatewayAddressException no longer appears in any stack trace from Routes.getRunnableProjects.

FAQ

Does Ignition 8.3.1 still throw MissingGatewayAddressException behind a TLS-terminating proxy?

The IGN-13832 path was fixed in the 8.3.0 final release and verified on 8.3.1 with an ingress forwarding to http/8088. The error still occurs on 8.3.1 through 8.3.7 when Auto Detect HTTP Address is enabled, which is tracked as IGN-15058. Turn off auto-detect and set the public address and ports manually.

Can I keep Use Proxy Forwarded Headers enabled for SSO without adding TLS to the gateway?

Yes. Keep gateway.useProxyForwardedHeader=true, disable Auto Detect HTTP Address, and set Public Address, HTTP Port (80), and HTTPS Port (443). The launcher then resolves the HTTPS branch from the configured public HTTPS port, with no certificate in Ignition.

Can I enable Force Secure Redirect when HTTPS terminates at Traefik or Nginx?

Yes, from 8.3.0-beta4 onward, by passing gateway.forceSecureRedirect=true as a gateway argument after --. The UI toggle is not available without HTTPS configured in Ignition. You can also redirect at the proxy instead.

Does the Ignition container need all three of -a, -h, and -s?

Yes. The public address options only apply when all three are supplied, for example -a ignition.k8s.localtest.me -h 80 -s 443. Use the ports clients hit on the proxy, not the container's 8088 or 8043.

Back to blog