Documentation Index
Fetch the complete documentation index at: https://tally.wharflab.com/llms.txt
Use this file to discover all available pages before exploring further.
HEALTHCHECK instruction missing.
| Property | Value |
|---|
| Severity | Ignore (off by default) |
| Category | Best Practice |
| Default | Off |
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
FROM busybox
HEALTHCHECK CMD /bin/health
or:
FROM busybox
HEALTHCHECK NONE
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.
| Platform | Suppressed image patterns |
|---|
| AWS Lambda | public.ecr.aws/lambda/*, gallery.ecr.aws/lambda/*, amazon/aws-lambda-* |
| Azure Functions | mcr.microsoft.com/azure-functions/* |
| OpenFaaS | openfaas/of-watchdog, openfaas/classic-watchdog (including ghcr.io variants) |
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.
| Framework | Example |
|---|
Google Cloud Functions (functions-framework) | CMD ["functions-framework", "--target=hello"] |
The exec prefix commonly used in shell form is handled:
CMD exec functions-framework --target=hello --port=$PORT
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:
CMD ["bash"] # exec form
CMD bash # shell form
CMD ["bash", "-l"] # shell with flags (still interactive)
ENTRYPOINT ["/bin/sh"] # entrypoint shell
Not suppressed when the shell is used to execute a command:
CMD ["bash", "-c", "my-app"] # runs my-app, not interactive
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.
FROM nginx:latest
RUN echo "custom config" > /etc/nginx/conf.d/default.conf
EXPOSE 80
# No CMD — nginx base image provides CMD and likely HEALTHCHECK
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:
FROM alpine AS base
CMD ["my-app"]
FROM base
RUN echo "setup"
# DL3057 still fires — CMD inherited from "base", 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