Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/traefik/traefik/llms.txt

Use this file to discover all available pages before exploring further.

Migration Guide: From v2 to v3

Migrate from Traefik Proxy v2 to v3 with confidence using this comprehensive guide that minimizes risk and ensures a smooth transition.
Traefik v3 introduces minimal breaking changes and maintains backward compatibility with v2 syntax in dynamic configuration, offering a gradual migration path.

Overview

Traefik v3 streamlines the migration process from v2 by:
  • Introducing minimal breaking changes in static configuration
  • Maintaining backward compatibility with v2 syntax in dynamic configuration
  • Providing a gradual path for adopting v3 syntax
  • Allowing progressive migration of Kubernetes resources, Docker labels, and other dynamic configurations

Migration Strategy

The migration consists of three progressive steps designed to minimize risk:
1

Prepare and Test

Update static configurations, enable v2 compatibility mode, and thoroughly test in a non-production environment.
2

Deploy to Production

Progressively roll out Traefik v3 to production instances using a rolling update strategy.
3

Migrate Dynamic Configuration

Gradually migrate dynamic configurations from v2 to v3 syntax on a per-router basis.

Step 1: Prepare Configurations and Test v3

This step focuses on updating static configurations and enabling backward compatibility for safe testing.

1.1 Review Static Configuration Changes

Review all breaking changes in static configuration that affect Traefik v3:

Docker Provider Changes

In v3, Docker provider has been split into two separate providers: Before (v2):
providers:
  docker:
    swarmMode: true
After (v3):
providers:
  swarm:
    endpoint: "tcp://127.0.0.1:2377"
The swarmMode option is no longer supported in the Docker provider. Use the dedicated Swarm provider instead.

Removed Providers

The following providers have been removed in v3:
  • Rancher v1 Provider - Rancher v1 is no longer maintained. Use Kubernetes CRD provider for Rancher 2.x
  • Marathon Provider - Marathon maintenance ended October 31, 2021

HTTP/3 Configuration

HTTP/3 is no longer experimental and the experimental.http3 option has been removed. Before (v2):
experimental:
  http3: true
After (v3):
entryPoints:
  websecure:
    address: ":443"
    http3:
      advertisedPort: 443

Namespace Options

Consul, ConsulCatalog, and Nomad providers now use namespaces (plural) instead of namespace: Before (v2):
consul:
  namespace: foobar
After (v3):
consul:
  namespaces:
    - foobar

TLS Configuration

The tls.caOptional option has been removed from all providers (Docker, Consul, ConsulCatalog, Nomad, HTTP, ETCD, Redis).

Deprecated Features Removed

  • InfluxDB v1 metrics provider (maintenance ended 2021)
  • Traefik Pilot configuration (no longer available since October 2022)

1.2 Enable v2 Compatibility Mode

Add the following to your static configuration to maintain v2 syntax compatibility:
core:
  defaultRuleSyntax: v2
[core]
  defaultRuleSyntax = "v2"
--core.defaultRuleSyntax=v2
This configuration makes v2 format the default for rule matchers syntax, allowing your existing dynamic configuration to work without modification.

1.3 Update Kubernetes Resources

If using Kubernetes providers, update your resources:

Update CRDs

# Update Traefik CRDs to v3
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.6/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml

# Update RBAC for TCPServersTransport support
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.6/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml

Update API Versions

  • CRD API Group: Change from traefik.containo.us to traefik.io
  • Ingress API: Ensure you’re using networking.k8s.io/v1 (v1beta1 is removed)
  • CRD API Version: Use apiextensions.k8s.io/v1 (v1beta1 is removed)

1.4 Test in Non-Production Environment

1

Start Traefik v3

Deploy Traefik v3 with updated static configuration in your test environment.
2

Monitor Startup

Check logs for errors or warnings during startup.
3

Validate Routing

Test all routes and ensure applications are accessible.
4

Check Middleware

Verify all middleware configurations work correctly.

Validation Checklist

  • ✅ Traefik starts without error logs
  • ✅ All routes are functioning correctly
  • ✅ Applications are accessible through Traefik
  • ✅ SSL/TLS termination works as expected
  • ✅ Middleware behavior is unchanged
  • ✅ Metrics and observability are working
Do not proceed to production until all validation checks pass successfully.

Step 2: Migrate Production Instances to Traefik v3

This critical step migrates your production environment to Traefik v3.

2.1 Pre-Migration Requirements

Before migrating production:
Critical Requirements:
  • ✅ Real-time monitoring solution for ingress traffic
  • ✅ Rollback plan documented and tested
  • ✅ Team availability during migration window
  • ✅ Backup of current configuration
  • ✅ Communication plan for stakeholders

2.2 Progressive Deployment Strategy

Use a progressive migration strategy to minimize risk:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: traefik
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    spec:
      containers:
      - name: traefik
        image: traefik:v3.6
        # ... rest of configuration
Apply the update:
kubectl apply -f deployment.yaml
kubectl rollout status deployment/traefik
docker service update \
  --image traefik:v3.6 \
  --update-parallelism 1 \
  --update-delay 30s \
  traefik
  1. Deploy v3 instances alongside v2 (green environment)
  2. Route a small percentage of traffic to v3
  3. Monitor metrics and error rates
  4. Gradually increase traffic to v3
  5. Decommission v2 instances once fully migrated

2.3 Monitor During Migration

Activate debug logging for detailed troubleshooting:
log:
  level: DEBUG

accessLog: {}
Key Metrics to Monitor:
  • Request success rate (2xx/3xx responses)
  • Error rate (4xx/5xx responses)
  • Response time percentiles (p50, p95, p99)
  • Active connections
  • Backend health check status

2.4 Rollback Procedure

If issues arise, execute your rollback plan immediately:
# View rollout history
kubectl rollout history deployment/traefik

# Rollback to previous version
kubectl rollout undo deployment/traefik

# Rollback to specific revision
kubectl rollout undo deployment/traefik --to-revision=2
docker service rollback traefik

Step 3: Progressively Migrate Dynamic Configuration

This optional step migrates dynamic configuration from v2 to v3 syntax. It can be completed after production migration.
This step is optional and can be done at your own pace. Traefik v3 remains compatible with v2 dynamic configuration syntax.

3.1 Understanding v3 Syntax Changes

Router Rule Matchers

Key changes in v3 syntax:
v2 Syntaxv3 SyntaxNotes
HeadersHeaderSingular form
HeadersRegexpHeaderRegexpSingular form
PathPrefix with regexPathRegexpPathPrefix no longer uses regex
Path with {id} placeholdersPathRegexpPlaceholders no longer supported
HostHeaderHostHostHeader removed
Regex Syntax:
  • v3 uses Go regexp syntax for all matchers
  • All matchers take single values (except Header, HeaderRegexp, Query, QueryRegexp)
  • Matchers must be explicitly combined using logical operators

3.2 Migration Examples

Example 1: Path Matcher Migration

Before (v2):
rule: "Host(`example.com`) && Path(`/api`, `/v1/api`)"
After (v3):
rule: "Host(`example.com`) && (Path(`/api`) || Path(`/v1/api`))"

Example 2: Path Placeholders to PathRegexp

Before (v2):
rule: "Host(`example.com`) && Path(`/products/{id}`)"
After (v3):
rule: "Host(`example.com`) && PathRegexp(`^/products/[^/]+$`)"

Example 3: Headers to Header

Before (v2):
rule: "Headers(`X-Custom-Header`, `value`)"
After (v3):
rule: "Header(`X-Custom-Header`, `value`)"

Example 4: Complex PathPrefix Migration

Before (v2):
rule: "Host(`example.com`) && PathPrefix(`/api/{version}`)"
After (v3):
rule: "Host(`example.com`) && PathRegexp(`^/api/[^/]+`)"

3.3 Per-Router Migration Strategy

Migrate routers individually using the ruleSyntax option:
labels:
  - "traefik.http.routers.myapp.rule=Host(`example.com`) && Path(`/api`)"
  - "traefik.http.routers.myapp.ruleSyntax=v3"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: myapp
  namespace: default
spec:
  routes:
    - match: Host(`example.com`) && Path(`/api`)
      syntax: v3
      kind: Rule
      services:
        - name: myapp
          port: 80
http:
  routers:
    myapp:
      rule: "Host(`example.com`) && Path(`/api`)"
      ruleSyntax: v3
      service: myapp
[http.routers.myapp]
  rule = "Host(`example.com`) && Path(`/api`)"
  ruleSyntax = "v3"
  service = "myapp"

3.4 Migration Process

1

Select Router

Start with non-critical services or development/staging routers.
2

Update Syntax

Convert the router rule to v3 syntax and add ruleSyntax: v3.
3

Test Thoroughly

Verify the router works correctly with v3 syntax in a test environment.
4

Deploy

Apply the updated configuration to production.
5

Monitor

Watch for errors and validate traffic is routing correctly.
6

Repeat

Move to the next router and repeat the process.

3.5 Middleware Changes

Update middleware names if using deprecated options: IPWhiteList Renamed:
# v2
middlewares:
  - ipwhitelist

# v3 (configuration unchanged, just renamed)
middlewares:
  - ipallowlist
Removed Headers Middleware Options:
  • sslRedirect
  • sslTemporaryRedirect
  • sslHost
  • sslForceHost
  • featurePolicy
StripPrefix Middleware:
  • The forceSlash option has been removed

3.6 Final Cleanup

Once all routers are migrated to v3 syntax:
1

Remove Compatibility Mode

Remove the core.defaultRuleSyntax: v2 from your static configuration.
2

Restart Traefik

Apply the configuration change and restart Traefik instances.
3

Verify

Ensure all routes continue to work without v2 compatibility mode.
4

Clean Logs

Check logs for any deprecation warnings and address them.
# Remove this entire section from static configuration
core:
  defaultRuleSyntax: v2  # DELETE THIS

Post-Migration Verification

After completing all migration steps, verify the deployment:

Final Checklist

  • ✅ All routers use v3 syntax
  • ✅ v2 compatibility mode disabled
  • ✅ No deprecated warnings in logs
  • ✅ All applications functioning correctly
  • ✅ Performance metrics stable or improved
  • ✅ Observability (metrics, tracing, logs) working
  • ✅ SSL/TLS certificates renewing correctly
  • ✅ Health checks passing
  • ✅ Middleware behaving as expected

Observability Changes

Be aware of these observability changes in v3: Metrics:
  • Open connections metric is now global: traefik_open_connections (replaces per-entrypoint/router/service metrics)
  • gRPC status codes now use the Grpc-Status header value
Tracing:
  • Now powered exclusively by OpenTelemetry (OTLP)
  • Direct vendor formats (Jaeger, Zipkin, Datadog, Elastic, etc.) are no longer supported
  • Use OTLP ingestion endpoints or OpenTelemetry collectors
Access Logs:
  • ServiceURL field is now a string (not an object)
  • Update any log indexing that relies on this field
Internal Resources:
  • Observability for internal routers/services is disabled by default
  • Enable with addInternals option in AccessLogs, Metrics, or Tracing

Common Issues and Solutions

Symptoms: Traefik exits immediately with configuration errorsSolutions:
  • Check for deprecated static configuration options
  • Verify swarmMode is not used with Docker provider
  • Remove experimental.http3 option
  • Update namespace options to plural form
  • Remove tls.caOptional from provider configurations
Symptoms: 404 errors for previously working routesSolutions:
  • Ensure core.defaultRuleSyntax: v2 is set during migration
  • Check if PathPrefix rules need conversion to PathRegexp
  • Verify path placeholders are converted to PathRegexp
  • Update Headers/HeadersRegexp to Header/HeaderRegexp
Symptoms: Kubernetes Ingress paths with regex not matchingSolutions:
  • Add annotation: traefik.ingress.kubernetes.io/router.rulesyntax: v2
  • Or convert regex to Go syntax and use PathRegexp matcher
  • Or use traefik.ingress.kubernetes.io/router.pathmatcher annotation
Symptoms: Missing metrics after upgradeSolutions:
  • Update to new metric names (e.g., traefik_open_connections)
  • Enable internal resources with addInternals: true
  • Remove references to removed metrics (config reload failures)
Symptoms: No traces appearing in tracing backendSolutions:
  • Migrate to OpenTelemetry configuration
  • Use OTLP-compatible endpoints
  • Configure OpenTelemetry collector if needed
  • Check OTLP exporter configuration

Additional Resources

Congratulations! You have successfully migrated to Traefik v3. Take advantage of new features like passive health checks, TCP health checks, and improved load balancing strategies.