Forgejo and Gitea: job log expired
A job log that a Forgejo or Gitea server no longer has is not late: the server removed it when its keeping time ran out. The job log API then answers 404, Forgejo with {"message":"logs have expired"}, Gitea with {"message":"logs have been cleaned up"}. The keeping time is LOG_RETENTION_DAYS in the [actions] section of the server configuration, 365 days by default, counted from when the job stopped. A cleanup task removes the logs past it every night at midnight and deletes the files, so raising the setting afterwards keeps the remaining logs longer but does not bring removed ones back.
What the servers answer
Gitea, checked in 28.2.0, the latest release, of October 18, 2026 (routers/common/actions.go):
- 404
logs have been cleaned upfromGET /api/v1/repos/{owner}/{repo}/actions/jobs/{job_id}/logs: the log was removed. - 404
job not started: the job has not run yet; its log comes when it does. - 404
unable to open task logs: ...: the server still lists a log file that its storage no longer has. GET .../actions/runs/{run}/logs, a zip of the latest attempt, leaves out the jobs whose logs are gone, and answers 404logs not foundwhen none is left.
Forgejo, from its source (services/actions/job_logs.go, routers/api/v1/repo/action.go):
- 404
logs have expiredfromGET /api/v1/repos/{owner}/{repo}/actions/jobs/{job_id}/logs: the log was removed. - 404
job has not been executed yet: the job has not run yet. - 404
step index out of range: thestepasked for is past the last step of the job. GET .../actions/runs/{run_id}/logs, a zip, puts a file named{job}-{id}-attempt-{n}.MISSINGin place of each removed log, holding the wordslogs have been cleaned up.
How long logs and runs are kept
- Gitea:
LOG_RETENTION_DAYS, 365 by default; 0 keeps logs forever (docs.gitea.com: Configuration Cheat Sheet, services/actions/cleanup.go). Gitea also deletes completed runs and everything under them afterRUN_RETENTION_DAYS, 400 by default, 0 for never; after that the run itself answers 404. Artifacts go afterARTIFACT_RETENTION_DAYS, 90 by default. - Forgejo:
LOG_RETENTION_DAYS, 365 by default (forgejo.org: Configuration Cheat Sheet). A value of 0 or less is read as 365 (modules/setting/actions.go), so there is no setting that keeps logs forever. - Both: the days count from when the job stopped, and a job still running is never removed (
FindOldTasksToExpirein models/actions/task.go). The removal is the cron taskcleanup_actions, at midnight by default (services/cron/tasks_actions.go).
To keep a log past that time, download it while the server still has it: the run logs zip above, or the log of one job.
Forgejo and Gitea Actions in IntelliJ IDEA
Pipeline Inbox for Forgejo and Gitea, a plugin by Lesstep for JetBrains IDEs 2024.1 or later, shows the log of each job in a tab of the IDE. Version 1.0.0 said This job has no log for a finished job whose log the server removed; version 1.0.1 says that the server removed it, and names LOG_RETENTION_DAYS. The runs, jobs and logs are free; re-running, cancelling and starting workflows are Pro (US$1.50 a month, with a 30-day trial).
Get it on JetBrains Marketplace
Forgejo, Gitea and Codeberg are names of their respective owners; IntelliJ IDEA is a trademark of JetBrains s.r.o. This page is not affiliated with or endorsed by the Forgejo project, Codeberg e.V., the Gitea project or JetBrains.
More: "No matching online runner with label" · Workflow dispatch refused · Gitea Actions API "token is required" · Forgejo Actions and Gitea Actions in JetBrains IDEs · 日本語