Introduction
Traefik configuration errors occur when the static or dynamic configuration files contain syntax errors, invalid directives, or incompatible settings. These errors prevent Traefik from starting or loading the intended routing rules, leaving services unreachable. Traefik supports both YAML and TOML formats, each with specific syntax requirements and common pitfalls.
Symptoms
Error messages in Traefik logs:
Error while building configuration: yaml: line 15: mapping values are not allowed here
Error during configuration parsing: field not found: invalidField
near line 10: unknown field "http" in type *static.Configuration
Error reading dynamic configuration: unexpected EOFObservable indicators: - Traefik fails to start with config error - Routers or services not appearing in dashboard - Changes to config files have no effect - Traefik ignores certain configuration blocks - API returns incomplete configuration data
Common Causes
- 1.YAML indentation errors - Wrong number of spaces or mixing tabs
- 2.Invalid field names - Using deprecated or non-existent fields
- 3.Version incompatibility - Using v2 config syntax with v3
- 4.Missing required fields - Incomplete configuration blocks
- 5.Invalid data types - String where number expected, etc.
- 6.TOML syntax errors - Missing brackets, wrong sections
- 7.Duplicate keys - Same key defined multiple times
- 8.Invalid YAML anchors - Malformed anchor references
Step-by-Step Fix
Step 1: Validate Configuration Syntax
```bash # Test configuration without starting Traefik traefik --configFile=/etc/traefik/traefik.yml --check
# Docker - validate before deploy docker run --rm -v ./traefik.yml:/etc/traefik/traefik.yml \ traefik:v3.0 --configFile=/etc/traefik/traefik.yml --check
# Use YAML linter yamllint traefik.yml yamllint -d relaxed traefik.yml # Less strict
# For TOML files tomll < traefik.toml > /dev/null
# Check JSON equivalent python3 -c "import yaml, json; json.dumps(yaml.safe_load(open('traefik.yml')))" ```
Step 2: Fix YAML Indentation Errors
```yaml # WRONG: Inconsistent indentation providers: docker: endpoint: "unix:///var/run/docker.sock" # 3 spaces exposedByDefault: false # 4 spaces
# CORRECT: Consistent 2-space indentation providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false
# WRONG: Tabs mixed with spaces (will show as error) entryPoints: web: address: ":80" # This might be a tab
# CORRECT: Spaces only entryPoints: web: address: ":80" ```
```bash # Check for tabs in YAML grep -P '\t' traefik.yml
# Convert tabs to spaces expand -t 2 traefik.yml > traefik-fixed.yml ```
Step 3: Fix Invalid Field Names
```yaml # WRONG: Deprecated v2 fields in v3 # AccessLog format changed accessLog: format: common # Deprecated
# CORRECT: v3 syntax accessLog: format: json fields: defaultMode: keep
# WRONG: Incorrect field path
http:
routers:
myapp:
rule: Host(app.example.com) # Missing backticks
# CORRECT: Proper rule syntax
http:
routers:
myapp:
rule: "Host(app.example.com)"
```
# Common field name errors and corrections
# v2 -> v3 migration
# routersPath -> routers
# middlewaresPath -> middlewares
# servicesPath -> servicesStep 4: Fix Missing Required Fields
```yaml # WRONG: Missing required fields certificatesResolvers: myresolver: acme: email: admin@example.com # Missing storage field
# CORRECT: Complete ACME configuration certificatesResolvers: myresolver: acme: email: admin@example.com storage: /letsencrypt/acme.json httpChallenge: entryPoint: web
# WRONG: Incomplete entrypoint entryPoints: web: # Missing address
# CORRECT: entryPoints: web: address: ":80" ```
Step 5: Fix Data Type Errors
```yaml # WRONG: Number as string entryPoints: web: address: ":80" # This is correct # But: forwardedHeaders: trustedIPs: "10.0.0.0/8" # Should be array
# CORRECT: entryPoints: web: address: ":80" forwardedHeaders: trustedIPs: - "10.0.0.0/8" - "172.16.0.0/12"
# WRONG: Boolean as string providers: docker: exposedByDefault: "false" # String instead of boolean
# CORRECT: providers: docker: exposedByDefault: false ```
Step 6: Fix TOML Configuration Errors
```toml # WRONG: Missing section headers [entryPoints] [entryPoints.web] address = ":80"
# CORRECT: Proper TOML structure [entryPoints.web] address = ":80"
[entryPoints.websecure] address = ":443"
# WRONG: Invalid TOML array [[http.services.myservice.loadBalancer.servers]] url = "http://10.0.0.1:8080" url = "http://10.0.0.2:8080" # Duplicate key
# CORRECT: Multiple server entries [[http.services.myservice.loadBalancer.servers]] url = "http://10.0.0.1:8080"
[[http.services.myservice.loadBalancer.servers]] url = "http://10.0.0.2:8080" ```
Step 7: Fix Dynamic Configuration Errors
yaml
# dynamic.yml - File provider dynamic configuration
http:
routers:
myapp:
rule: "Host(app.example.com`)"
service: myapp-service
entryPoints:
- websecure
tls:
certResolver: myresolver
services: myapp-service: loadBalancer: servers: - url: "http://internal-server:8080" healthCheck: path: /health interval: 30s ```
```bash # Validate dynamic configuration docker run --rm -v ./dynamic.yml:/etc/traefik/dynamic.yml \ traefik:v3.0 --configFile=/etc/traefik/traefik.yml --check
# Check loaded dynamic config via API curl http://localhost:8080/api/http/routers curl http://localhost:8080/api/http/services ```
Step 8: Version Migration
```yaml # Traefik v2 to v3 migration checklist
# 1. IngressRoute API version change # v2: apiVersion: traefik.containo.us/v1alpha1
# v3: apiVersion: traefik.io/v1alpha1
# 2. Middleware changes # v2: - "traefik.http.middlewares.compress.compress=true"
# v3: - "traefik.http.middlewares.compress.compress={}"
# 3. Kubernetes CRD updates # Apply new CRDs for v3 kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/pkg/provider/kubernetes/crd/traefik.io.yaml ```
Step 9: Verify Configuration
```bash # After fixes, validate and restart traefik --configFile=/etc/traefik/traefik.yml --check && echo "Config valid"
# Restart Traefik docker-compose restart traefik
# Check API for loaded configuration curl -s http://localhost:8080/api/overview | jq curl -s http://localhost:8080/api/http/routers | jq curl -s http://localhost:8080/api/http/services | jq curl -s http://localhost:8080/api/providers | jq ```
Advanced Diagnosis
Debug Configuration Loading
```yaml # Enable debug logging to see config loading details log: level: DEBUG filePath: /var/log/traefik/traefik.log
# Enable API for inspection api: dashboard: true insecure: true # Development only ```
# Watch logs during startup
docker logs -f traefik 2>&1 | grep -i "configuration\|error\|warn"Compare Configurations
```bash # Export current running config curl -s http://localhost:8080/api/rawdata | jq '.' > current-config.json
# Compare with file diff <(yq eval -o json traefik.yml) current-config.json ```
Split Configuration Files
```yaml # Use multiple config files for easier debugging # traefik.yml - static config entryPoints: web: address: ":80"
providers: file: directory: /etc/traefik/dynamic watch: true ```
# /etc/traefik/dynamic/routers.yml
http:
routers:
myapp:
rule: "Host(`app.example.com`)"
service: myapp# /etc/traefik/dynamic/services.yml
http:
services:
myapp:
loadBalancer:
servers:
- url: "http://internal:8080"Common Pitfalls
- Copy-paste errors - Invisible characters or wrong indentation
- Version mismatch - Using v2 docs with v3 or vice versa
- Missing quotes - Rules and URLs need quotes in YAML
- Wrong nesting level - Fields placed under wrong parent
- Typo in field names - Case-sensitive field names
- Empty values - Required fields left empty or null
Best Practices
```yaml # Organize configuration clearly # traefik.yml api: dashboard: true
log: level: INFO
entryPoints: web: address: ":80" http: redirections: entryPoint: to: websecure scheme: https websecure: address: ":443"
providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false network: traefik file: filename: /etc/traefik/dynamic.yml watch: true
certificatesResolvers: letsencrypt: acme: email: admin@example.com storage: /letsencrypt/acme.json httpChallenge: entryPoint: web ```
# Pre-commit hook for config validation
#!/bin/bash
# .git/hooks/pre-commit
for file in $(git diff --cached --name-only | grep -E '\.(yml|yaml|toml)$'); do
echo "Validating $file..."
if [[ $file == *.yml ]] || [[ $file == *.yaml ]]; then
yamllint "$file" || exit 1
fi
traefik --configFile="$file" --check || exit 1
doneRelated Issues
- Traefik Start Failed
- Traefik Docker Provider Error
- Traefik Routing Not Working
- Traefik Middleware Error