Skip to content

Link Check flaky under GitHub rate-limiting (live URLs reported dead on many-link runs) #316

Closed

Description

@wz-gsa

Problem

The Link Check CI job (tcort/github-action-markdown-link-check) intermittently fails by reporting live URLs as dead, when a run checks many github.com (and nvd.nist.gov) links at once and gets rate-limited. Observed across multiple PRs (#313, #315) on consecutive runs — the flagged links (issues, commits, compare URLs, repo roots) all resolve 200 in a browser; CI sees Status: 0 (connection reset) or 503.

Root cause: the checker is unauthenticated, so it hits GitHub's low anonymous rate limit and GitHub sheds load with 503/reset rather than 429. retryOn429: true does not catch 503/0, so the retry path never engages.

Impact: approved, green-everywhere-else PRs sit UNSTABLE and need repeated manual re-runs; the failure is non-deterministic and unrelated to the PR's diff. This is a CI-reliability defect, not a content problem.

Proposed fix (config-hardening, main)

  1. Treat transient throttling statuses as alive for the retry path — add 429, 503 (and, guardedly, 0) handling. Since the checker's aliveStatusCodes already lists bot-block 403, add 429/503 there too so a throttled probe defers instead of failing. (0 is trickier — it also means real DNS failure — so prefer the retry/GitHub-auth route below over blanket-ignoring 0.)
  2. Reduce GitHub-specific throttling: pass a token to the action so github.com links are checked authenticated (5000/hr vs ~60/hr). The action supports it; use the workflow's GITHUB_TOKEN (read-only, no secret to manage) — this is the real fix, eliminating most 0/503.
  3. Bump retryCount/fallbackRetryDelay modestly as belt-and-suspenders.

Least-privilege note: the token would be the default read-only GITHUB_TOKEN; no new secret, no elevated scope.

Acceptance

  • Link Check passes deterministically across consecutive runs on a PR touching many github.com links.
  • Real dead links still fail (verify with a known-404).
  • No new secret / no elevated permission beyond read-only GITHUB_TOKEN.

Recurring workaround being retired: PRs #313/#315 each needed manual Link Check re-runs for this. AI-assisted (OpenCode). Requires human review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions