docker/compose · error
healthcheck.start_interval requires healthcheck.start_period
Error message
healthcheck.start_interval requires healthcheck.start_period to be set
What it means
When converting a compose healthcheck to the engine's container.HealthConfig, pkg/compose/convert.go maps start_interval; due to moby/moby#48874 the engine misbehaves when start_interval is set without start_period, so compose enforces that start_period must be explicitly set whenever start_interval appears. Absence of start_period with a non-nil start_interval aborts service conversion.
Source
Thrown at pkg/compose/convert.go:74
if check.Timeout != nil {
timeout = time.Duration(*check.Timeout)
}
if check.StartPeriod != nil {
period = time.Duration(*check.StartPeriod)
}
if check.Retries != nil {
retries = int(*check.Retries)
}
test := check.Test
if check.Disable {
test = []string{"NONE"}
}
var startInterval time.Duration
if check.StartInterval != nil {
startInterval = time.Duration(*check.StartInterval)
if check.StartPeriod == nil {
// see https://github.com/moby/moby/issues/48874
return nil, errors.New("healthcheck.start_interval requires healthcheck.start_period to be set")
}
}
return &container.HealthConfig{
Test: test,
Interval: interval,
Timeout: timeout,
StartPeriod: period,
StartInterval: startInterval,
Retries: retries,
}, nil
}
// ToSeconds convert into seconds
func ToSeconds(d *compose.Duration) *int {
if d == nil {
return nil
}
s := int(time.Duration(*d).Seconds())View on GitHub (pinned to ddc4b044b6)
Solutions
- Add an explicit start_period to the healthcheck, e.g. `start_period: 10s`, alongside start_interval.
- If the fast-fail startup probing is not needed, remove start_interval entirely.
- Keep both values tuned together (start_interval typically smaller than start_period) when you need quick failure detection during startup.
Example fix
# before
services:
web:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
start_interval: 5s
# after
services:
web:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
start_period: 30s
start_interval: 5s Defensive patterns
Strategy: validation
Validate before calling
# fail fast on start_interval without start_period if grep -q 'start_interval:' compose.yaml && ! grep -q 'start_period:' compose.yaml; then echo "healthcheck.start_interval requires start_period" >&2 exit 1 fi
Prevention
- Always set start_period whenever you set start_interval (mobu/moby#48874 constraint).
- Run docker compose config in CI to catch invalid healthcheck pairs before deploy.
When it happens
Trigger: A service defined as `healthcheck: { test: [...], interval: 10s, start_interval: 5s }` with no `start_period` key, then running docker compose up/create/config on any engine — the guard fires regardless of engine version because compose rejects it up front.
Common situations: Copy-pasting healthcheck snippets from docs that show start_interval alone; migrating compose files from setups that relied on implicit start_period defaults; CI validating compose files failing on previously 'fine' configs after upgrading compose.
Related errors
- 'compose' is not a valid provider type
- your Compose stack cannot be published as it only contains a
- watch rules MUST define a path
- service %q build configuration does not support platform: %s
- required parameter %q is missing from provider %q definition
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/0f341ee0ec955cef.
Report an issue: GitHub.