traefik/traefik
Debugging
Things that go wrong while developing on Traefik, and where to look.
Increase log verbosity
Traefik uses github.com/rs/zerolog. The setup lives in pkg/observability/logs/logs.go and is wired by setupLogger in cmd/traefik/traefik.go.
To get debug-level logs:
./traefik --log.level=DEBUG --configFile=traefik.sample.toml--log.format=json switches to structured output. Field names are stable: time, level, message, entryPointName, routerName, serviceName, etc. The package-level helpers (logs.Logger(ctx)) propagate context-scoped fields.
Access logs are separate. They are emitted by pkg/middlewares/accesslog and configured under accessLog: in static configuration. Toggle with --accesslog=true.
Inspect the live runtime
The dashboard is the fastest way to see what configuration Traefik is actually running:
./traefik --api.insecure --providers.file.filename=traefik.toml
# Open http://localhost:8080/dashboard/The dashboard reads from the HTTP API in pkg/api/handler.go. The same data is queryable directly:
GET /api/overview
GET /api/http/routers
GET /api/http/services
GET /api/http/middlewares
GET /api/tcp/routers
GET /api/udp/routers
GET /api/entrypointspkg/api/handler_overview.go shows the top-level shape; handler_http.go, handler_tcp.go, and handler_udp.go cover the protocol-specific endpoints. The runtime model used to answer them lives in pkg/config/runtime — every router, service, and middleware carries a Status and an Err field describing why it's healthy or not.
Common failure shapes
"router cannot be enabled" with no routes appearing
A provider produced a router whose service or middleware references something that does not exist, or whose rule does not parse. The runtime status will show the reason. Check:
- The dashboard's "Errors" tab.
routerName.Errin the JSON returned by/api/http/routers.- The startup log at
--log.level=DEBUG—pkg/server/router/router.gologs each rejection.
Configuration changes are not applied
The configuration watcher deduplicates messages per provider. If two messages from the same provider produce identical configurations, only the first is applied. Look for log messages from pkg/server/configurationwatcher.go:
Skipping unchanged configuration for provider XProvider polling intervals (exposedByDefault, pollInterval, watch implementations) live per provider. If your edits to a Docker label do not appear, check that your container is running and that the discovery loop in pkg/provider/docker/pdocker.go is logging.
TLS certificate not served
Two paths can serve a certificate:
- A static-config certificate listed under
tls.certificates(pkg/tls/tlsmanager.go). - An ACME-resolved certificate (
pkg/provider/acme/provider.go).
Look for log lines from tlsmanager.go ("certificate not found for domain X") or acme/provider.go ("Unable to obtain ACME certificate"). The ACME state (account, certificates) is stored in the file referenced by the resolver's storage field — pkg/provider/acme/local_store.go.
"Cannot decode configuration" at startup
pkg/cli and github.com/traefik/paerser parse configuration. Most "cannot decode" errors are field name typos. Compare your YAML/TOML against the schema in pkg/config/static/static_config.go (every field has json, yaml, toml, and description tags).
Plugin fails to load
pkg/plugins/manager.go logs the failure with the plugin name and source path. Check:
- The plugin's
.traefik.ymlmanifest is valid (parsed bypkg/plugins/types.go). - For Yaegi plugins: the entry point function signature matches the documented interface.
- For Wasm plugins: the export names match what
pkg/plugins/middlewarewasm.goexpects.
Useful CLI subcommands
traefik version— prints version, codename, build date.traefik healthcheck— invokes the health-check probe (uses static config to find the ping address).traefik --help— auto-generated from the static-configuration tags.
Reproducing in tests
Most behaviors can be reproduced as either:
- A unit test in
pkg/server/router/router_test.go(build a synthetic dynamic config, assert on the constructed handler). - An integration test in
integration/(boot a real binary against fixtures).
Integration tests are the right tool when the bug involves real network behavior (TLS, HTTP/2, HTTP/3, WebSocket upgrades, gRPC trailers).
Pprof and runtime introspection
Enable pprof by setting --api.debug=true. Endpoints are mounted at /debug/pprof/... by pkg/api/debug.go. Useful when chasing leaks or hotspots in the proxy or the configuration loop.
The metrics middleware (pkg/middlewares/metrics) exposes per-router/per-service counters when a metrics backend is configured. Even without a backend, the /metrics endpoint shows current values once Prometheus is enabled in static config.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.