Skip to main content
HEALTHCHECK instruction missing.

Description

This is an optional rule. When it is required to define a health check (e.g. by company policy), it must not be omitted. This rule is disabled by default because a HEALTHCHECK is not desirable in all circumstances. Images used with Kubernetes do not benefit from a HEALTHCHECK instruction, as Kubernetes brings its own mechanisms.

Examples

Problematic code

Correct code

or:

tally enhancements

Smart suppression

tally automatically suppresses this rule when the Dockerfile shows strong signals that a HEALTHCHECK would not be beneficial:

Serverless / FaaS base images

Containers built for serverless platforms have their lifecycle managed externally — the platform decides when to start, stop, and replace function instances. A container-level HEALTHCHECK is ignored in these environments. If any stage in the Dockerfile uses a recognized serverless base image, the violation is suppressed for the entire file. Multi-stage builds that pull from a Lambda image in one stage and copy artifacts into another are still covered because the presence of the serverless image signals the target runtime.

Serverless framework entrypoints

When the final stage’s CMD or ENTRYPOINT invokes a known serverless function framework, the container is a short-lived function handler managed by the platform — not a service that benefits from HEALTHCHECK. The exec prefix commonly used in shell form is handled:

Interactive / shell-only containers

When the final stage’s CMD or ENTRYPOINT resolves to a bare interactive shell (sh, bash, zsh, ash, dash, fish, csh, tcsh, ksh), the container is clearly not a long-running service — there is no endpoint to health-check. Recognized patterns:
Not suppressed when the shell is used to execute a command:
If an ENTRYPOINT is present, it takes precedence over CMD (matching Docker runtime semantics).

No explicit CMD/ENTRYPOINT (external parent delegation)

When the final stage has no CMD or ENTRYPOINT instruction and its base is an external image (not another build stage), the image delegates run orchestration to its parent. In these cases the parent likely also defines a HEALTHCHECK, so flagging the child produces false positives. The violation is suppressed.
This does not apply when the final stage inherits from a prior build stage (FROM <stage-name>), because CMD/ENTRYPOINT are inherited from the prior stage and the image is not opaque:

Explicit opt-out with HEALTHCHECK NONE

HEALTHCHECK NONE is treated as a deliberate opt-out. When present in any stage, DL3057 is fully suppressed — no fast-path violation is emitted and no async registry checks are planned. This matches Docker’s semantics where HEALTHCHECK NONE explicitly disables health checking.

Async registry resolution

tally extends this rule with async registry resolution (enabled with --slow-checks):
  • Base image inspection: For each external base image, tally checks if it already defines a HEALTHCHECK in its image metadata. If so, the violation is suppressed since the health check is inherited. This check is skipped when any explicit HEALTHCHECK instruction (CMD or NONE) is already present.
  • Cross-rule awareness: buildkit/MultipleInstructionsDisallowed may still flag duplicate HEALTHCHECK instructions even when DL3057 is suppressed.

Reference