Skip to content
Latchkey LogoLatchkey home

GitHub Actions step debug logs truncated, and where the rest is

GitHub Actions step debug logs truncated describes a problem with reading the log rather than with the log itself, and that distinction is the whole fix: the stored run log is not the thing that gave up. Before hunting for a size limit, get the archive, because the line you want is very often already in it.

Three ways to read a job output, with what each one gives you and what it leaves out
Three routes to the same output. The web viewer is the only one that has to render in a browser, and the only one that struggles.

What this error means

You switch on step debug logging to chase something, re-run the job, and the web view of the step will not show you what you came for. The view is slow to open, scrolling stalls, and the part of the output you need is above or below whatever the browser is willing to render. What makes this frustrating is that the run succeeded in producing the output: the command wrote it, the runner uploaded it, and only the last step of getting it in front of you has failed.

The command that retrieves the stored log, not a message from a run
gh run download <run-id> --log > run.log   # the archive, not the viewer
wc -l run.log

A note on the message people expect to find

Many descriptions of this problem quote a warning line saying that the logs for a step have been truncated because they exceeded a maximum size. We went looking for that line and could not establish it. Searched as an exact phrase and as its longest fragment, with a nonsense phrase of the same shape as a control returning nothing and real messages returning results that did contain them, the phrase produced no report whose body carried it once fetched and searched.

It is also absent from the sources you can read. The runner repository does not contain it, and the documentation on run logs and on debug logging does not describe a truncation warning or publish a step log size limit. The documented limits page covers workflow file size, job concurrency and storage, and says nothing about the size of a step log.

The honest conclusion is narrow. A sentence that is widely repeated is not one we can attribute to anything, and we are not going to repeat it as though it were quoted. What people do reliably experience is a web view that will not show them everything, which is a real problem with a real answer, and the rest of this page is about that.

How you read the outputWhat you getLimited by rendering
The step view in the browseras much as the page will renderyes
The downloaded run log archivethe stored log for every jobno
An artifact you uploaded yourselfexactly what you redirected into itno
The runner diagnostic logsthe runner and worker process logsno

Common causes

Step debug logging was left on repository wide

The switch is not scoped to one workflow or one job, so every run in the repository becomes verbose until somebody removes it. A single investigation can make every log in the repository harder to read for as long as it stays set.

A tool was run at its most verbose setting

Build tools, package managers and test runners can produce enormous output on request. A verbosity flag added during one investigation and never removed is the usual origin of a permanently unreadable step.

The output belongs in a file rather than in the log

Large structured output, reports and traces are better as artifacts. Putting them in the log makes them hard to read and hard to keep, since a log is not a convenient thing to hand to somebody else.

The browser is the constraint, not the log

In our experience this is where most of the confusion sits. The stored log is complete, and the view of it is the part that is failing, which is why downloading the archive so often ends the problem in one command.

How to fix it

Download the log archive and search it

  1. Download the run log rather than scrolling the step view.
  2. Search the downloaded file for the text you need.
  3. If you need a different job from the same run, it is in the same archive.
shell
gh run download <run-id> --log > run.log
grep -n -C3 'error' run.log

Redirect verbose output into an artifact

Capture the noisy command into a file, upload the file, and print it only when the step fails. The log stays readable and the full output is downloadable for as long as the artifact is retained.

.github/workflows/ci.yml
- run: npm run build --verbose > build.log 2>&1 || { tail -50 build.log; exit 1; }
- if: always()
  uses: actions/upload-artifact@v4
  with:
    name: build-log
    path: build.log

Turn step debug logging off again

Remove the repository secret or variable once the investigation is finished. Treat it as a temporary change with an owner, not as a setting that can be left on because it is sometimes useful.

Use the debug context to be verbose only when watched

Guard expensive or noisy steps on the runner debug context so they run when somebody has actually turned debug logging on. This keeps the ordinary log clean without losing the detail when it is wanted.

.github/workflows/ci.yml
- if: runner.debug == '1'
  run: |
    env | sort
    cat package-lock.json | head -100

Add the runner diagnostic logs when the question is about the runner

Setting the runner debug variable adds the runner and worker process logs to the archive. Use it when a step did not start or the job set up looks wrong, rather than when a command printed too much.

Getting the whole log, and what the archive contains

The stored log for a run can be downloaded as an archive, and that is the copy to work with whenever the browser is struggling. It contains the log for every job in the run, so it also answers questions the step view makes awkward, such as what a different job was doing at the same moment.

Once it is on disk the tools are the ordinary ones. Searching a file for a pattern is faster and more reliable than scrolling, and it does not care how large the file is. This is usually the entire fix, and it takes less time than reading an explanation of a size limit.

There is a second switch worth knowing about, distinct from step debug logging. Turning on runner diagnostic logging adds two files to the archive, one from the runner process about coordinating and setting up the job and one from the worker process about executing it. Those answer questions about the runner rather than about your commands, which makes them the right tool when the problem is that a step did not start rather than that it printed too much.

shell
gh run download <run-id> --log > run.log
grep -n 'the thing you are looking for' run.log

# or from the API
gh api repos/OWNER/REPO/actions/runs/<run-id>/logs > logs.zip

Producing less, so there is less to read

Step debug logging is a repository wide switch. Setting it affects every job in every workflow in that repository until it is turned off, which is why a single investigation can make everybody logs unreadable for a week. Turn it off when you are done, and treat leaving it on as a change rather than a convenience.

Where the noise comes from your own commands rather than from the runner, redirect it. Sending verbose output to a file and uploading that file as an artifact gives you a complete copy that was never in the log at all, and it keeps the step view usable for the rest of the job. Print the file on failure so a red run still carries its evidence.

There is also a context that lets a workflow know whether debug logging is on, which means a step can decide to be verbose only when somebody is actually looking. That is a better pattern than a permanently noisy step, because it gives you the output when you want it and costs nothing when you do not.

.github/workflows/ci.yml
- name: Build
  run: npm run build --verbose > build.log 2>&1 || { cat build.log; exit 1; }

- if: always()
  uses: actions/upload-artifact@v4
  with:
    name: build-log
    path: build.log

- if: runner.debug == '1'
  run: env | sort

Why there is no recorded run on this page

The subject here is a browser failing to render a large page, which is not a property of a run at all. A recording would be a video of our browser on our machine, and the thing it demonstrated would be our hardware and our connection rather than anything about GitHub Actions.

It would also be the wrong evidence for the most important claim on the page, which is a negative one. The way to support the statement that the expected warning line cannot be attributed is to describe the search and its controls, which is done above, not to produce a run that does not show it.

Nor is there anything to repair. A log that is too large to render comfortably is a successful log, and the command that wrote it did what it was told.

How to prevent it

  • Treat step debug logging as a temporary change with somebody responsible for removing it.
  • Send large or structured output to an artifact rather than to the log.
  • Guard noisy diagnostic steps on the runner debug context.
  • Reach for the downloaded archive before you fight the web viewer.

Frequently asked questions

Is there a documented size limit on a GitHub Actions step log?
Not one we can point at. The documented limits cover workflow file size, job concurrency and storage, and do not mention a step log size. The widely quoted warning about logs being truncated for exceeding a maximum size is not something we could attribute to the runner or the documentation.
How do I get the complete log for a run?
Download the run log archive, which contains the stored log for every job, and search the file with ordinary tools. This is almost always faster than fighting the web view, and it does not depend on what a browser is willing to render.
Does ACTIONS_STEP_DEBUG affect only one workflow?
No. It is set as a repository secret or variable, so it applies to every job in every workflow in that repository until it is removed. That is why one investigation can leave every log in the repository verbose.
What is the difference between step debug and runner diagnostic logging?
Step debug logging makes the job log more verbose. Runner diagnostic logging adds two separate files to the log archive, one from the runner process about coordinating and setting up the job and one from the worker process about executing it.

Related guides

References

The log is fine and the viewer gave up. Latchkey cuts how many runs you have to read at all. Start free → 30-day trial · No credit card