Articles
Traefik Interview Questions: Routers, Middleware, and Service Discovery
Trace Traefik routers, middleware order, provider namespaces, and backend discovery with request examples, failure checks, and interview practice.
A request reaches Traefik, the container is running, and the dashboard shows a router. The browser still receives a 404. A useful interview answer explains which request was matched, which transformations ran, and which endpoint received the result. Listing reverse-proxy features does not locate the failure.
This article develops that answer through an original routing exercise and a service-discovery investigation. Official facts come from current Traefik documentation. Worked examples and diagnostic recommendations are original practice and inference, not candidate reports or claims about a particular employer's interview. The configuration examples use the Traefik v3 model and HTTP routing; check the installed version before carrying over older syntax.
For a practical starting point, use Debug and Improve a Load Balancer to explain your evidence before proposing a routing change.
How does Traefik turn a request into an upstream call?
Official fact: an HTTP router evaluates a rule, invokes its configured middlewares when it matches, and forwards the request to a service. Middlewares run in their declared order. Traefik's HTTP router reference defines those relationships.
A clear answer assigns a separate job to each object. An entryPoint accepts traffic on a configured listening address. The router decides whether the incoming host, path, and other rule conditions match. Middleware may reject or transform the request. The service identifies the backend arrangement used to handle it.
In an interview, draw the request twice: once as the client sent it and once as the backend sees it. This prevents a common reasoning error: assuming a rewritten path was used to select the router in the first place.
Suppose a client sends GET https://shop.example/api/orders/42. Your answer should identify the listening entryPoint, the original host and path, the selected router, the middleware chain, and the service endpoint. Also state where TLS terminates. A diagram saying only “client → proxy → server” leaves all the disputed decisions hidden.
The distinction matters operationally. A healthy backend can receive the wrong path. A correct router can point to an unreachable service. A discovered container can lack a usable routing rule. Each condition requires different evidence, even when all three produce an unsuccessful browser request.
Which overlapping router wins?
Consider this original exercise. Two file-provider HTTP routers share the same entryPoint:
http:
routers:
shop:
rule: "Host(`shop.example`)"
priority: 10
service: storefront
orders:
rule: "Host(`shop.example`) && PathPrefix(`/api/`)"
priority: 20
middlewares:
- remove-api
service: orders-api
middlewares:
remove-api:
stripPrefix:
prefixes:
- /api
services:
storefront:
loadBalancer:
servers:
- url: http://storefront:8080
orders-api:
loadBalancer:
servers:
- url: http://orders:9000
This is the dynamic file configuration. It assumes the entryPoint and file provider were enabled separately and that those backend names resolve from Traefik's network. It is not a complete deployment manifest.
Predict three requests before changing anything:
| Original request | Matching routers | Selected service | Backend path after configured stripping |
|---|---|---|---|
shop.example/api/orders/42 | shop, orders | orders-api, priority 20 | /orders/42 |
shop.example/catalog | shop | storefront, priority 10 | /catalog |
shop.example/apix/orders | shop | storefront, priority 10 | /apix/orders |
The trailing slash in PathPrefix(`/api/`) is deliberate: the exercise separates the intended namespace from /apix. The exact /api path also falls outside that prefix, so decide whether it needs a separate match or redirect. Do not assume the example covers every URL your product accepts.
The important explanation is that both rules match the first request, but the explicit higher priority selects orders. The stripping happens afterward. It cannot retroactively make a different router match.
Official fact: when no overriding priority is supplied, Traefik orders routes by rule length; a priority of zero uses that default. “The most specific-looking path wins” is therefore an unsafe substitute for inspecting the actual rules. Explicit priorities make the intended overlap easier to review, but they still require tests when rules change.
What changes when middleware order changes?
Official fact: StripPrefix removes configured prefixes and records them in X-Forwarded-Prefix. The backend must still serve the resulting path. Stripping a prefix does not create the application's routes.
Use an authorization check as the next original reasoning exercise. Imagine an authorization component whose policy evaluates the request path it receives. If the chain is authorization then stripping, it evaluates /api/orders/42. If stripping precedes authorization, it evaluates /orders/42 under that assumed policy.
Neither order is universally correct. Ask which path the policy contract expects, which headers the authorization service trusts, and whether the application uses the same interpretation. An answer saying “authentication should always run first” misses the distinction between identity verification and authorization against a transformed resource name.
The test should record both the policy input and the backend input. Include an allowed route, a denied route, an encoded-path case relevant to your application, and an unknown path. Success means the policy protects the actual resource that the backend serves, not merely that the happy-path request returns 200.
For a chain containing a rate limiter, also explain what happens to rejected requests. A limiter before authorization may count unauthenticated attempts; a limiter afterward may operate only on requests that passed the earlier check. Whether that is desirable depends on the quota and abuse-control requirements.
These are design conclusions from the exercise, not undocumented guarantees about every middleware. Consult the specific middleware's contract rather than treating the chain as a list of interchangeable labels.
What does service discovery actually discover?
Official fact: Traefik providers supply routing configuration, and objects belong to provider namespaces. A reference such as shared-auth@file identifies a middleware from the file provider. The provider overview explains that namespace model.
Distinguish startup configuration from routing configuration. Listening addresses and provider activation are setup decisions. A provider can then expose changing routers, middlewares, and services as workloads change. Finding a container does not prove that every object expected by a router exists or belongs to the same provider.
Consider an application defined through Docker labels that references shared-auth@file. Check that the file provider is enabled and that its current configuration actually contains that middleware. A same-looking middleware name in another provider is not sufficient. Name qualification should be visible in your explanation, not discovered only after a failed deployment.
Official fact: the Docker provider documentation describes exposure controls and backend port selection. With exposedByDefault=false, a workload must be explicitly enabled for discovery into routing. A container exposing several ports should have its intended backend port specified.
That control is a sensible deployment starting point when only selected services should receive traffic. It is not a complete authorization policy: the discovered route still needs appropriate access controls, and the provider's access to Docker also deserves a deliberate deployment design.
In a concrete interview investigation, ask whether labels were placed on the object the selected provider reads. Docker and Swarm are separate provider contexts; assumptions about container labels and service labels must match the actual deployment. Then inspect the effective router and service rather than relying only on the source Compose file.
Why does a running container still produce a gateway error?
Use this diagnostic matrix, which is an inference framework rather than a status-code guarantee:
| Observation | Evidence to inspect next | Change justified only after confirmation |
|---|---|---|
| Request appears to miss every intended router | Actual host, path, entryPoint, TLS mode and effective rules | Correct the mismatch or missing route |
| A router matches but references an unavailable middleware | Provider-qualified name and provider configuration errors | Repair the reference or object definition |
| Selected service points to the wrong container port | Effective server address and application listening port | Set the intended service port |
| Endpoint is correct but unreachable | Shared network, name resolution and connectivity from Traefik | Repair the network or backend availability |
| Backend receives the request but returns 404 | Transformed path and backend routing logs | Align prefix handling with application routes |
A 404 alone does not establish that Traefik failed to select a router: the backend can return it. Likewise, a gateway error does not identify whether the cause is DNS, the port, network attachment, or the backend process. Preserve the selected router, service, endpoint, and upstream status as separate observations where your logging configuration exposes them.
Suppose the container publishes host port 19000 but the application listens on container port 9000. Do not automatically set the upstream to 19000. Determine the address Traefik uses and the port reachable at that address. In a shared container network, the application's internal port is usually the relevant one; the exact topology decides the answer.
Now suppose the container belongs to an application network and an unrelated management network. Explain which network Traefik can reach and how provider configuration selects it. Merely restarting the proxy can hide a selection problem without making the deployment deterministic.
How would you make the routing change reviewable?
Describe the expected request contract before presenting YAML. Include accepted hosts, paths, TLS requirements, the post-middleware path, and the backend port. Then identify which configuration objects change. A review becomes easier when it can compare those expectations with a small diff.
For the worked example, a useful regression set contains /api/orders/42, /catalog, /apix/orders, and the intentionally unresolved /api case. Add a request with the wrong host and a backend outage. Those cases test both selection and failure behavior rather than repeating one successful request.
If you change middleware order, preserve evidence of the policy input before and after. If you change discovery settings, verify the intended workload is included and an unrelated workload remains excluded. If you add a broad fallback router, demonstrate that it does not capture traffic intended for a more narrowly controlled service.
Explain rollout and rollback in terms of the effective configuration. A successful deployment command is not proof that a provider accepted every object. After the change, compare the loaded router, middleware references, service endpoints, and a small set of requests with the contract you wrote down.
A strong spoken answer might be: “I will identify the original request, prove which router selected it, trace the ordered middleware changes, and test the selected endpoint from the proxy's network. Then I will change the first contract that is demonstrably wrong.” That is a reproducible investigation, not a guess based on one HTTP status.
Practice the adjacent engineering decisions
| Question | What to explain alongside this article |
|---|---|
| Debug and Improve a Load Balancer | Separate a routing defect from an unreachable backend. |
| Design a Software Load Balancer | Connect endpoint selection to discovery and request handling. |
| Design a High-Availability Load Balancer | Explain failure detection and the remaining single points of failure. |
| Design load balancing, caching, and idempotent APIs | Keep proxy retries separate from application mutation safety. |
| Explain worker state machine load balancer design | Describe endpoint readiness as an explicit state transition. |
Start with the load-balancer debugging exercise. Explain one failed request aloud, then write the smallest configuration change and the requests that would prove it worked.