✦ For everyone, free.

Practical knowledge for real and everyday life

Home

15.1.3.5 Log Driver Misconfig

A focused guide to Log Driver Misconfig, connecting core concepts with practical Docker and container operations.

Log driver misconfiguration covers the category of logging problems caused not by the application or by genuine infrastructure failure, but by an incorrect or mismatched driver setting, an invalid option value, an unreachable endpoint specified incorrectly, or inconsistent configuration between the daemon default and an individual container's override, each producing a distinct and recognizable failure pattern.

Containers failing to start due to invalid driver options

An invalid or malformed --log-opt value can prevent a container from starting at all, since the daemon validates logging configuration as part of container creation:

docker run -d --log-driver=fluentd --log-opt fluentd-address=not-a-valid-address my-api
Error response from daemon: failed to initialize logging driver: dial tcp: address not-a-valid-address: missing port in address

This class of failure is usually straightforward to diagnose, since the daemon's error message at container creation time typically points directly at the malformed option, but it is worth specifically checking the exact syntax expected for address-style options, since drivers differ in whether they expect a bare hostname, a full URL with scheme, or a host:port pair.

Containers starting but unable to deliver logs

A more subtle failure occurs when a driver's configuration is syntactically valid but points at an endpoint that is unreachable, which often does not prevent the container from starting at all, since the daemon may not validate actual reachability at creation time, only the configuration's structural validity:

docker run -d --log-driver=gelf --log-opt gelf-address=udp://wrong-host:12201 my-api
docker logs my-api
Error response from daemon: configured logging driver does not support reading

Since drivers like gelf do not support local read-back, there is often no immediate, visible symptom of the misconfiguration beyond logs simply never arriving at their intended destination, which makes verifying actual delivery, rather than only verifying that the container started successfully, an important separate check.

Daemon default and container-level override conflicts

When a daemon-wide default logging configuration exists alongside per-container or per-Compose-service overrides, confusion about which configuration is actually in effect for a specific container is a common source of unexpected behavior:

{
  "log-driver": "local",
  "log-opts": { "max-size": "10m" }
}
services:
  api:
    logging:
      driver: json-file

In this example, the api service explicitly overrides the daemon's default driver, which means none of the daemon-level log-opts (configured for the local driver) apply to it at all, since those options are specific to the driver they were configured under; an operator expecting the daemon's rotation settings to apply universally would be surprised to find this container's logs growing unbounded.

docker inspect my-api --format '{{json .HostConfig.LogConfig}}'

Checking the actual effective configuration directly through docker inspect, rather than assuming based on the daemon configuration file alone, resolves this category of confusion quickly.

Mismatched assumptions about read-back support

A common misconfiguration pattern is choosing a write-only remote driver without realizing it disables docker logs, then being confused when a routine debugging workflow that relied on that command stops working:

docker run -d --log-driver=awslogs --log-opt awslogs-group=my-logs my-api
docker logs my-api
Error response from daemon: configured logging driver does not support reading

This is not actually a misconfiguration in the sense of something being broken; the driver is working exactly as designed, but the operator's assumption about available tooling did not match the driver's actual capabilities, which is most often resolved by either querying the actual destination directly or enabling dual logging if local access is genuinely needed alongside the remote driver.

Incorrect option names due to driver-specific syntax

Each logging driver has its own set of valid --log-opt keys, and using an option name valid for one driver while configured for a different one typically results in the option being silently ignored rather than producing an error, which can be more confusing than an outright failure:

docker run -d --log-driver=syslog --log-opt max-size=10m my-api

max-size is a json-file and local driver option and has no meaning for the syslog driver, which does not perform local rotation at all; this option is simply ignored rather than causing a startup error, leaving an operator who expected it to bound something believing a limit is in effect when none actually exists for that driver.

Verifying configuration after any change

Any change to logging driver configuration, whether at the daemon level or for an individual container, is worth verifying directly against a freshly created container rather than assumed to have taken effect correctly:

docker run -d --name verify-logging-test my-api:1.4.0
docker inspect verify-logging-test --format '{{json .HostConfig.LogConfig}}'
docker logs verify-logging-test
docker rm -f verify-logging-test

A brief verification step like this, run immediately after a daemon restart following a configuration change, confirms the new configuration is actually being applied as intended before relying on it for production containers.

Common mistakes

  • Assuming daemon-level logging defaults apply to every container, without accounting for per-container or per-Compose-service overrides that replace rather than merge with the daemon default.
  • Using a driver-specific option under a different, incompatible driver, where it is silently ignored rather than producing a visible error.
  • Choosing a write-only remote driver and being surprised when docker logs stops working, rather than recognizing this as expected behavior for that driver category.
  • Not verifying actual log delivery to a remote endpoint, relying only on the container having started successfully as evidence that logging is working correctly.
  • Failing to re-verify logging configuration after a daemon restart or configuration change, assuming the change took effect without confirming it directly.

Log driver misconfiguration is usually resolvable quickly once the specific symptom, a startup failure, silent delivery failure, or an unexpectedly inactive option, is matched against the right category of cause, and verifying actual effective configuration directly through docker inspect and confirmed log delivery is more reliable than reasoning about what should be in effect based on configuration files alone.