<a id="how-to-troubleshoot-reachability"></a>

# How to troubleshoot reachability

After integrating Traefik to your charm, you may encounter reachability errors such as:

- Internal server error
- 404 page not found

## Checklist

- Your charm either uses open-port<sup>[1](https://canonical.com/juju/docs/juju-cli/3.6/reference/hook-command/list-of-hook-commands/open-port/#hook-command-open-port),[2](https://github.com/canonical/operator/pull/905)</sup> or applies a [Kubernetes service patch](https://github.com/canonical/observability-libs/blob/main/lib/charms/observability_libs/v1/kubernetes_service_patch.py) for exposing the workload’s port.
- Your workload is not bound to a particular IP address, i.e. it is listening on “0.0.0.0”.
- You either pass `strip_prefix=True` to the ingress library, or your workload’s Pebble command includes the path prefix generated by Traefik (`/model_name-app_name`) so your app is serving correctly.
- The Subject Alternative Names in your workload’s certificate match the URL in Traefik’s configuration.
- Traefik trusts the same CA that signed your workload’s certificate.
- Inspect logs.

## Workload is correctly exposed

`juju ssh` into the charm container and run `ss -tulpn`. Find your app’s port in the list and make sure it is not bound to a particular IP, e.g.

```default
Local Address:Port
            *:3200
            *:9096
```

Also make sure Kubernetes has your ports listed as ClusterIP, for example:

`user@host:~$ ``kubectl -n welcome-k8s get svc         `
```text
NAME    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                   AGE
tempo   ClusterIP   10.152.183.237   <none>        3200/TCP,4317/TCP,4318/TCP,9411/TCP,14268/TCP,14250/TCP   30m
```

## Ingress path prefix is handled correctly

By default, Traefik uses deterministic paths to all proxied endpoints, such as `http://<traefik ip>/model_name-app_name`.

This means that you need to tell your workload about it (for example, Alertmanager takes a `--web.external-url` CLI argument)
or tell Traefik to strip prefix:

```python
        self.ingress = IngressPerAppRequirer(
            self,
            "ingress",
            port=self._port,
            scheme=lambda: "https" if self.server_cert.cert else "http",
            redirect_https=True,
            strip_prefix=True,
        )
```

## Workload’s certificate has the correct SAN DNS

To avoid using `insecureSkipVerify` in Traefik configuration, the URL specified in the Traefik configuration must match the DNS in the certificate.

Shell into the Traefik workload container to confirm:

`user@host:~$ ``juju ssh --container traefik trfk/0 bash`
```text
root@trfk-0:/# cat /opt/traefik/juju/juju_ingress_ingress_48_am.yaml | grep url
        - url: https://am-0.am-endpoints.welcome-k8s.svc.cluster.local:9093
root@trfk-0:/# echo | openssl s_client -showcerts -connect am-0.am-endpoints.welcome-k8s.svc.cluster.local:9093 | openssl x509 -text | grep DNS
                DNS:am-0.am-endpoints.welcome-k8s.svc.cluster.local
```

## Traefik trusts the same CA that signed your workload’s certificate

To avoid using `insecureSkipVerify` in Traefik configuration, Traefik must trust the CA that signed the proxied app’s certificate.

Shell into the Traefik workload container to confirm:

`user@host:~$ ``juju ssh --container traefik trfk/0 bash`
```text
root@trfk-0:/# cat /opt/traefik/juju/juju_ingress_ingress_48_am.yaml | grep -E "url|cert"
      - /opt/traefik/juju/ca.cert
        - url: https://am-0.am-endpoints.welcome-k8s.svc.cluster.local:9093
root@trfk-0:/# curl --capath /opt/traefik/juju \
    --cacert /opt/traefik/juju/ca.cert \
    https://am-0.am-endpoints.welcome-k8s.svc.cluster.local:9093/welcome-k8s-am/-/ready
OK
```

## Inspect Traefik’s log

Make sure Traefik is running.

`user@host:~$ ``juju ssh --container traefik trfk/0 /charm/bin/pebble changes traefik`
```text
ID   Status  Spawn               Ready               Summary
1    Done    today at 13:20 UTC  today at 13:20 UTC  Replan service "traefik"

juju ssh --container traefik trfk/0 /charm/bin/pebble tasks 1        

Status  Spawn               Ready               Summary
Done    today at 13:20 UTC  today at 13:20 UTC  Start service "traefik"
```

Look at the Traefik log as you add or remove relations:

```default
kubectl -n welcome-k8s logs pods/trfk-0 -c traefik -f
```
