Introduction
Traefik routing problems occur when requests don't reach the expected backend services. This can manifest as 404 errors, requests going to wrong services, or complete routing failures. Traefik's dynamic configuration model relies on proper labels, annotations, or file configurations, and routing issues often stem from rule matching problems, priority conflicts, or service discovery failures.
Symptoms
Error messages in Traefik logs:
"No matching service found"
"Router has no middleware"
"Service not found"
"Cannot create service: missing port"Observable indicators: - Requests return 404 Not Found - Requests routed to wrong backend - Dashboard shows routers/services as errors or warnings - Health checks failing for configured routes - TLS certificates not applied
Common Causes
- 1.Router rule mismatch - Host or path rule doesn't match incoming request
- 2.Service definition missing - Router points to non-existent service
- 3.Port configuration wrong - Service port doesn't match container port
- 4.Priority conflict - Multiple routers match, wrong one selected
- 5.EntryPoints not configured - Router not attached to correct entrypoint
- 6.Docker label issues - Missing or incorrect labels
- 7.Kubernetes IngressRoute errors - Resource misconfiguration
Step-by-Step Fix
Step 1: Check Traefik Dashboard
```bash # Access Traefik dashboard (if enabled) # Typically at http://localhost:8080 or via IngressRoute
# Or use API curl http://localhost:8080/api/http/routers curl http://localhost:8080/api/http/services curl http://localhost:8080/api/http/services/my-service
# Check router status curl http://localhost:8080/api/http/routers | jq '.[] | {name: .name, rule: .rule, service: .service, status: .status}' ```
Step 2: Verify Router Configuration
yaml
# docker-compose.yml with proper labels
services:
myapp:
image: myapp:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(app.example.com`)"
- "traefik.http.routers.myapp.entrypoints=websecure"
- "traefik.http.routers.myapp.tls.certresolver=myresolver"
- "traefik.http.services.myapp.loadbalancer.server.port=8080"
networks:
- traefik
networks: traefik: external: true ```
Step 3: Check Kubernetes IngressRoute
# IngressRoute with proper configuration
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: myapp
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: myapp-service
port: 80
namespace: default
tls:
secretName: myapp-tls```bash # Check IngressRoute status kubectl get ingressroutes.traefik.io -o yaml
# Check Traefik logs kubectl logs -n traefik deployment/traefik -f
# Describe IngressRoute for events kubectl describe ingressroute myapp ```
Step 4: Fix Rule Matching Issues
yaml
# Correct rule syntax
labels:
# Single host
- "traefik.http.routers.myapp.rule=Host(app.example.com`)"
# Multiple hosts
- "traefik.http.routers.myapp.rule=Host(app.example.com) || Host(www.example.com)"
# Host with path prefix
- "traefik.http.routers.myapp.rule=Host(api.example.com) && PathPrefix(/v1)"
# Path with regex
- "traefik.http.routers.myapp.rule=Host(api.example.com) && PathPrefix(/api/{version:[0-9]+})"
# Header-based routing
- "traefik.http.routers.myapp.rule=Host(api.example.com) && Headers(X-Version, v2)"
```
Step 5: Configure Priority Correctly
yaml
# Set priority for overlapping routes
labels:
# More specific route gets higher priority
- "traefik.http.routers.api-v2.rule=Host(api.example.com) && PathPrefix(/v2`)"
- "traefik.http.routers.api-v2.priority=100"
- "traefik.http.routers.api-v1.rule=Host(
api.example.com) && PathPrefix(/v1)" - - "traefik.http.routers.api-v1.priority=90"
# Catch-all should have lowest priority
- "traefik.http.routers.api-catchall.rule=Host(api.example.com)"
- "traefik.http.routers.api-catchall.priority=10"
```
Step 6: Fix Service Definition
yaml
# Docker labels - correct service configuration
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(app.example.com`)"
- "traefik.http.routers.myapp.service=myapp-service"
- "traefik.http.services.myapp-service.loadbalancer.server.port=8080"
- "traefik.http.services.myapp-service.loadbalancer.server.scheme=http"
# For multiple instances with different ports labels: - "traefik.http.services.myservice.loadbalancer.servers[0].url=http://10.0.0.1:8080" - "traefik.http.services.myservice.loadbalancer.servers[1].url=http://10.0.0.2:8080" ```
Step 7: Configure Entrypoints
```yaml # traefik.yml static configuration entryPoints: web: address: ":80" http: redirections: entryPoint: to: websecure scheme: https websecure: address: ":443" http: tls: {}
# Docker labels to use entrypoints labels: - "traefik.http.routers.myapp.entrypoints=websecure" ```
Step 8: Verify and Test
```bash # Test routing with curl curl -v -H "Host: app.example.com" http://localhost:80/
# Test with TLS curl -vk https://app.example.com/
# Check Traefik access logs docker logs traefik 2>&1 | grep -i error
# Validate configuration traefik --configFile=traefik.yml --configFile=dynamic.yml --check ```
Advanced Diagnosis
Debug Mode
```yaml # Enable debug logging api: dashboard: true insecure: true # Only for development
log: level: DEBUG
accessLog: filePath: /var/log/traefik/access.log format: json fields: defaultMode: keep headers: defaultMode: keep ```
Check Service Discovery
```bash # Docker provider - check containers are discovered curl http://localhost:8080/api/providers/docker
# Kubernetes provider - check resources curl http://localhost:8080/api/providers/kubernetes
# File provider - check loaded configs curl http://localhost:8080/api/providers/file ```
Health Check Configuration
labels:
- "traefik.http.services.myservice.loadbalancer.healthcheck.path=/health"
- "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s"
- "traefik.http.services.myservice.loadbalancer.healthcheck.timeout=5s"
- "traefik.http.services.myservice.loadbalancer.healthcheck.scheme=http"Middleware Issues
```yaml # Check middleware is applied labels: - "traefik.http.routers.myapp.middlewares=auth,rate-limit"
# Define middlewares - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..." - "traefik.http.middlewares.rate-limit.ratelimit.average=100" ```
Common Pitfalls
- Wrong port label - Using
traefik.portinstead ofloadbalancer.server.port - Missing traefik.enable - Docker containers need
traefik.enable=true - Network mismatch - Container not on Traefik's Docker network
- Rule syntax errors - Backticks not escaped, missing parentheses
- Service name mismatch - Router service doesn't match defined service name
- Namespace issues - Kubernetes IngressRoute in wrong namespace
- TLS resolver missing - Router expects TLS but no certresolver configured
Best Practices
```yaml # Complete Traefik configuration example # docker-compose.yml version: "3.8"
services: traefik: image: traefik:v3.0 command: - "--api.dashboard=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.myresolver.acme.tlschallenge=true" - "--certificatesresolvers.myresolver.acme.email=admin@example.com" - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./letsencrypt:/letsencrypt networks: - web
myapp:
image: myapp:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(app.example.com)"
- "traefik.http.routers.myapp.entrypoints=websecure"
- "traefik.http.routers.myapp.tls.certresolver=myresolver"
- "traefik.http.services.myapp.loadbalancer.server.port=8080"
- "traefik.http.services.myapp.loadbalancer.healthcheck.path=/health"
- "traefik.http.services.myapp.loadbalancer.healthcheck.interval=30s"
networks:
- web
networks: web: external: true ```
Related Issues
- Traefik SSL Certificate Error
- HAProxy Backend Down
- Nginx Upstream Not Balancing
- AWS ALB Health Check Failing