Introduction
Traefik routers fail to route traffic when labels are misconfigured, services aren't discovered, or middleware has errors. Requests return 404 Not Found or 502 Bad Gateway instead of reaching the backend service.
Symptoms
404 Not Found:
404 page not foundTraefik dashboard:
Router: my-app@docker
Status: No service found
Rule: Host(`app.example.com`)Traefik logs:
```bash $ docker logs traefik
time="2026-04-16T00:36:00Z" level=error msg="Cannot create service: service not found" time="2026-04-16T00:36:00Z" level=warning msg="No service found for router my-app" ```
Common Causes
- 1.Missing labels - Required Traefik labels not set
- 2.Wrong label syntax - Incorrect label format
- 3.Docker network - Container not on same network as Traefik
- 4.Service not running - Backend container stopped
- 5.Wrong rule - Host rule doesn't match request
- 6.Middleware error - Invalid middleware configuration
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Step 1: Check Traefik Dashboard
```bash # Access Traefik dashboard # Usually at http://localhost:8080
# Or via API curl http://localhost:8080/api/overview
# List routers curl http://localhost:8080/api/http/routers
# Get specific router curl http://localhost:8080/api/http/routers/my-app@docker
# List services curl http://localhost:8080/api/http/services
# List middlewares curl http://localhost:8080/api/http/middlewares
# Check for errors docker logs traefik 2>&1 | grep -i error ```
Step 2: Verify Docker Labels
```bash # Check container labels docker inspect my-app --format '{{json .Config.Labels}}' | jq
# Required labels for Docker provider:
# - traefik.enable=true
# - traefik.http.routers.<name>.rule=Host(example.com)
# - traefik.http.routers.<name>.entrypoints=web
# Example working labels:
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.rule=Host(app.example.com)"
- "traefik.http.routers.my-app.entrypoints=web"
- "traefik.http.services.my-app.loadbalancer.server.port=8080"
# Check labels in docker-compose: docker-compose config | grep -A 20 labels
# Common label mistakes:
# Wrong: traefik.http.routers.myapp.rule=Host('example.com')
# Correct: traefik.http.routers.myapp.rule=Host(example.com)
# Note: Use backticks not single quotes '
Step 3: Check Docker Network
```bash # List networks docker network ls
# Check container network docker inspect my-app --format '{{json .NetworkSettings.Networks}}' | jq
# Check Traefik network docker inspect traefik --format '{{json .NetworkSettings.Networks}}' | jq
# Containers must be on same network for Traefik to discover them
# Create network if not exists docker network create traefik
# Connect containers to network docker network connect traefik my-app docker network connect traefik traefik
# In docker-compose.yml: networks: traefik: external: true
services: my-app: networks: - traefik ```
Step 4: Fix Service Discovery
```yaml # Complete working docker-compose.yml
version: '3'
networks: traefik: external: true
services: traefik: image: traefik:v2.10 command: - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" ports: - "80:80" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock networks: - traefik
my-app:
image: my-app:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.rule=Host(app.example.com)"
- "traefik.http.routers.my-app.entrypoints=web"
- "traefik.http.services.my-app.loadbalancer.server.port=8080"
networks:
- traefik
# Start docker-compose up -d
# Verify docker-compose ps docker logs traefik ```
Step 5: Check Routing Rules
bash
# View router rule
curl -s http://localhost:8080/api/http/routers/my-app@docker | jq '.rule'
# Output: "Host(app.example.com`)"
# Test rule matching # The Host must match exactly (including port)
# WRONG: Rule for app.example.com but request to app.example.com:80 # CORRECT: Rule matches exactly
# For multiple hosts:
traefik.http.routers.my-app.rule=Host(app.example.com) || Host(www.example.com)
# For path prefix:
traefik.http.routers.my-app.rule=Host(example.com) && PathPrefix(/api)
# For regex:
traefik.http.routers.my-app.rule=HostRegexp({subdomain:[a-z]+}.example.com)
# Test with curl curl -H "Host: app.example.com" http://localhost/ ```
Step 6: Configure Load Balancer Port
```bash # Traefik needs to know which port the container listens on
# Method 1: Explicit port label labels: - "traefik.http.services.my-app.loadbalancer.server.port=8080"
# Method 2: Docker exposes port in Dockerfile EXPOSE 8080
# Method 3: Docker compose ports ports: - "8080:8080"
# Verify port detected docker inspect my-app --format '{{json .NetworkSettings.Ports}}'
# Check Traefik service curl -s http://localhost:8080/api/http/services/my-app@docker | jq '.loadBalancer.servers' # Should show: [{"url": "http://172.18.0.2:8080"}] ```
Step 7: Fix Middleware Issues
```bash # List middlewares curl http://localhost:8080/api/http/middlewares
# Check middleware errors docker logs traefik 2>&1 | grep -i middleware
# Common middleware configurations:
# Strip prefix: labels: - "traefik.http.middlewares.strip.stripprefix.prefixes=/api" - "traefik.http.routers.my-app.middlewares=strip"
# Rate limit: labels: - "traefik.http.middlewares.ratelimit.ratelimit.average=100" - "traefik.http.middlewares.ratelimit.ratelimit.burst=50" - "traefik.http.routers.my-app.middlewares=ratelimit"
# Basic auth: # Generate password: htpasswd -n admin labels: - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xxx" - "traefik.http.routers.my-app.middlewares=auth"
# Note: Double $$ in docker-compose, single $ in command line ```
Step 8: Configure HTTPS/TLS
```yaml # HTTPS with Let's Encrypt
services: traefik: image: traefik:v2.10 command: - "--api.insecure=true" - "--providers.docker=true" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true" - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" ports: - "80:80" - "443:443" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./letsencrypt:/letsencrypt
my-app:
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.rule=Host(app.example.com)"
- "traefik.http.routers.my-app.entrypoints=websecure"
- "traefik.http.routers.my-app.tls.certresolver=letsencrypt"
- "traefik.http.services.my-app.loadbalancer.server.port=8080"
# Create acme.json with correct permissions touch letsencrypt/acme.json chmod 600 letsencrypt/acme.json ```
Step 9: Debug Traefik Logs
```bash # Enable debug logging # In traefik command: command: - "--log.level=DEBUG"
# Or in traefik.yml: log: level: DEBUG
# Restart Traefik docker restart traefik
# Watch logs docker logs -f traefik
# Check for specific issues: docker logs traefik 2>&1 | grep -i "router|service|error"
# Common log patterns: # "Skipping container" - missing traefik.enable=true # "Provider connection error" - cannot connect to Docker socket # "Service not found" - wrong service name in router
# Access logs command: - "--accesslog=true" - "--accesslog.filepath=/var/log/traefik/access.log" ```
Step 10: Verify Complete Setup
```bash # Check Traefik is running docker ps | grep traefik
# Check Traefik can access Docker docker exec traefik ls /var/run/docker.sock
# Check router exists curl -s http://localhost:8080/api/http/routers | jq '.[] | select(.name=="my-app@docker")'
# Check service exists curl -s http://localhost:8080/api/http/services | jq '.[] | select(.name=="my-app@docker")'
# Check service has backend URL curl -s http://localhost:8080/api/http/services/my-app@docker | jq '.loadBalancer.servers'
# Test routing curl -H "Host: app.example.com" http://localhost/ -v
# Expected: Response from backend, not 404 ```
Traefik Router Troubleshooting Checklist
| Check | Command | Expected |
|---|---|---|
| Labels | docker inspect | traefik.enable=true |
| Network | docker network | Same as Traefik |
| Router | API /api/http/routers | Router exists |
| Service | API /api/http/services | Backend URLs |
| Rule | router.rule | Matches Host |
| Port | loadbalancer.server.port | Correct port |
Verification
```bash # After fixing router configuration
# 1. Check router status in dashboard # Visit http://localhost:8080 # Router should show as healthy
# 2. Test routing curl -H "Host: app.example.com" http://localhost/ # Should return response from backend
# 3. Check Traefik logs docker logs traefik --tail 50 # No errors
# 4. Verify service backend curl -s http://localhost:8080/api/http/services/my-app@docker | jq '.loadBalancer.servers' # Shows backend URL
# 5. Test from browser # Visit http://app.example.com # Should show application
# 6. Check access logs (if enabled) docker exec traefik cat /var/log/traefik/access.log | tail ```
Prevention
To prevent Traefik router issues from recurring, implement these proactive measures:
1. Validate Configuration Before Deployment
```bash # Check Traefik configuration validity traefik --configFile=/etc/traefik/traefik.yml --check
# For dynamic configuration validation: docker exec traefik traefik healthcheck ```
2. Monitor Router Health
groups:
- name: traefik
rules:
- alert: TraefikRouterDown
expr: traefik_router_service_up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Traefik router {{ $labels.router }} not working"3. Use Labels for Dynamic Routing
# docker-compose.yml with Traefik labels:
services:
app:
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`app.example.com`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls=true"
- "traefik.http.services.app.loadbalancer.healthcheck.path=/health"
- "traefik.http.services.app.loadbalancer.healthcheck.interval=30s"4. Configure Health Checks
# In traefik.yml:
http:
services:
my-service:
loadBalancer:
healthCheck:
path: /health
interval: 30s
timeout: 5s
scheme: httpBest Practices Checklist
- [ ] Validate configuration before deployment
- [ ] Monitor router status with alerts
- [ ] Use Docker labels for dynamic routing
- [ ] Configure service health checks
- [ ] Test routing rules in staging
- [ ] Document router configurations
Related Issues
- [Fix Traefik 502 Bad Gateway](/articles/fix-traefik-502-bad-gateway)
- [Fix Traefik SSL Certificate Error](/articles/fix-traefik-ssl-certificate-error)
- [Fix Traefik Service Not Found](/articles/fix-traefik-service-not-found)
Related Articles
- [Fix Fix Haproxy Backend 503 Issue in Load Balancer](fix-haproxy-backend-503)
- [How to Fix HAProxy Backend Connection Errors and 503 Failures](fix-haproxy-backend-connection-503-error-deep)
- [HAProxy All Backends Down: Complete Recovery Guide](fix-haproxy-backend-down-all)
- [Fix Fix Haproxy Backend Down Issue in Load Balancer](fix-haproxy-backend-down)
- [Fix HAProxy Backend Health Check Failed](fix-haproxy-backend-health-check-failed)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Traefik Router Not Working", "description": "Troubleshoot Traefik router issues. Check labels, middleware, and service discovery configuration.", "url": "https://www.fixwikihub.com/fix-traefik-router-not-working", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-05T02:06:37.247Z", "dateModified": "2026-04-05T02:06:37.247Z" } </script>