Repository navigation
ci: pre-commit red on main since 2026-08-03 (hadolint), blocking every open PR #1695
Description
The pre-commit workflow is failing on main and therefore on every open PR. Noticed while landing PR #1682, whose diff touches zero Dockerfiles yet inherits the red.
Symptom
pre-commit run --all-files (.github/workflows/pre-commit.yml:272) fails on the hadolint-docker hook, after all 3 retry attempts:
Lint Dockerfiles............................................................Failed
- hook id: hadolint-docker
- exit code: 1
Dockerfile:149 DL3066 info: Non-numeric user-id may not be resolvable by host system
Dockerfile:165 DL3025 warning: Use arguments JSON notation for CMD and ENTRYPOINT arguments
Dockerfile.dev:62 DL3066 info: Non-numeric user-id may not be resolvable by host system
Dockerfile.test:21 DL3066 info: Non-numeric user-id may not be resolvable by host system
Verified
- Failing on
mainitself, not only on PR branches: the four most recentpre-commitruns onmain(a8266881a,9de48ae74,f6bb36ab4,cd4ee031f, all 2026-08-03) arefailure, with byte-identical output. - Last green on
mainwas6ded40125(2026-07-28). - Nothing relevant changed in between. The four commits landed since
6ded40125touch noDockerfile*, no.hadolint.yaml, and no.pre-commit-config.yaml. Last change toDockerfilewasa840ed1d4(2026-07-10);.hadolint.yamlhas not changed since505480573(2026-02-20). - hadolint is pinned in
.pre-commit-config.yamlatrev: v2.14.0.
So the repository inputs are unchanged across the green-to-red transition.
Likely cause (not yet confirmed)
hadolint-docker runs through pre-commit's Docker image language, so the pinned rev fixes the tag, not the image digest. An upstream rebuild or re-tag of hadolint/hadolint:v2.14.0 would change the ruleset or default failure threshold underneath an unchanged pin. That matches the evidence (inputs unchanged, behaviour changed) but I have not diffed the image digests, so treat it as the leading hypothesis rather than an established root cause.
Worth ruling out first: whether the hook previously resolved to a cached image on the runner and now pulls a fresh one.
Fix direction
Whatever the root cause, the two decisions are separable:
- Restore a green gate. Either fix the four findings in the Dockerfiles (
DL3025is a genuine correctness nit: exec-formCMD/ENTRYPOINTavoids the shell wrapper and makes signal handling work;DL3066is about non-numericUSER), or pin the hook by digest so behaviour stops moving on its own. - Do not suppress. Adding
DL3025/DL3066to theignored:list in.hadolint.yamlwould turn the gate green without addressing either the findings or the fact that a pinned tool changed behaviour under a pin. If they are genuinely not worth fixing, that should be a recorded decision with a justification, not a quiet ignore entry.
Pinning by digest is the durable half regardless: see the existing pattern in #1297 / #1394 for tool-version alignment across ci.yml, pre-commit.yml and the Makefile.
Blast radius
Every open PR shows a red pre-commit check that is unrelated to its own diff, which trains reviewers to ignore that signal. That is the expensive part.
Activity
cristim commentedon Aug 3, 2026
Duplicate of #1696, which was filed first for the same problem and is fixed by PR #1697 (merged).
The root cause turned out to be sharper than this issue states: hadolint's own
.pre-commit-hooks.yamlatrev: v2.14.0declaresentry: ghcr.io/hadolint/hadolint hadolintwith no image tag, so Docker resolves:latest(currently 2.15.1). Therev:pin only fixes which commit of the hook definition is used, never the image it runs — so this was not a digest that drifted, it was a hook that was never image-pinned in the first place. Verified:docker run ghcr.io/hadolint/hadolint:v2.14.0 hadolint --version-> 2.14.0;:latest-> 2.15.1.No Dockerfile changes were needed or made. All four findings were new-rule noise from 2.15.x: DL3066 fires on any named
USER(all three are legitimate non-root switches afteradduser/addgroup), and DL3025 fired onHEALTHCHECK's embeddedCMDsub-clause rather than the realENTRYPOINT/CMD(already exec-form). Converting that to JSON form is not even possible without breaking the|| exit 1fallback, so editing the Dockerfiles would have introduced a bug for no gain.Closing as duplicate. The stray branch
chore/1695-hadolint-digest-pinhas no PR against it and can be deleted at leisure.fix(docker): adopt hadolint 2.15.1 and fix the four findings it reports
fix(docker): adopt hadolint 2.15.1 and fix the four findings it reports
chore(docker): adopt hadolint 2.15.1 and fix the four findings it rep…
chore(docker): adopt hadolint 2.15.1 and fix the four findings it rep…