-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Describe the bug
TempDirectoryManager fails to complete its information gathering phase when it encounters a file with permissions that do not allow it access, and the cleanup does not take place. This causes the temp directory to constantly grow, and subsequently cleanup jobs get longer and longer, and the disk to fill up.
We do not know how the directory (.ssh) came to have permissions that do not allow the service user (ghrunner) access to it.
Relevant log section;
[2026-02-16 17:25:30Z INFO TempDirectoryManager] Cleaning runner temp folder: /home/ghrunner/actions-runner/_work/_temp
[2026-02-16 17:31:43Z ERR TempDirectoryManager] System.AggregateException: One or more errors occurred. (Access to the path '/home/ghrunner/actions-runner/_work/_temp/_github_home/.ssh' is denied.)
---> System.UnauthorizedAccessException: Access to the path '/home/ghrunner/actions-runner/_work/_temp/_github_home/.ssh' is denied.
---> System.IO.IOException: Permission denied
--- End of inner exception stack trace ---
at System.IO.Enumeration.FileSystemEnumerator`1.Init()
at System.IO.DirectoryInfo.InternalEnumerateInfos(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
at GitHub.Runner.Sdk.IOUtil.Enumerate(DirectoryInfo directory, CancellationTokenSource tokenSource)+MoveNext()
at System.Linq.Parallel.PartitionedDataSource`1.ContiguousChunkLazyEnumerator.MoveNext(T& currentElement, Int32& currentKey)
at System.Linq.Parallel.SpoolingTaskBase.Work()
at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of inner exception stack trace ---
at System.Linq.Parallel.QueryTaskGroupState.QueryEnd(Boolean userInitiatedDispose)
at System.Linq.Parallel.SpoolingTask.SpoolForAll[TInputOutput,TIgnoreKey](QueryTaskGroupState groupState, PartitionedStream`2 partitions, TaskScheduler taskScheduler)
at System.Linq.Parallel.DefaultMergeHelper`2.System.Linq.Parallel.IMergeHelper<TInputOutput>.Execute()
at System.Linq.Parallel.MergeExecutor`1.Execute()
at System.Linq.Parallel.MergeExecutor`1.Execute[TKey](PartitionedStream`2 partitions, Boolean ignoreOutput, ParallelMergeOptions options, TaskScheduler taskScheduler, Boolean isOrdered, CancellationState cancellationState, Int32 queryId)
at System.Linq.Parallel.PartitionedStreamMerger`1.Receive[TKey](PartitionedStream`2 partitionedStream)
at System.Linq.Parallel.ForAllOperator`1.WrapPartitionedStream[TKey](PartitionedStream`2 inputStream, IPartitionedStreamRecipient`1 recipient, Boolean preferStriping, QuerySettings settings)
at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.ChildResultsRecipient.Receive[TKey](PartitionedStream`2 inputStream)
at System.Linq.Parallel.ScanQueryOperator`1.ScanEnumerableQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
at System.Linq.Parallel.QueryOperator`1.GetOpenedEnumerator(Nullable`1 mergeOptions, Boolean suppressOrder, Boolean forEffect, QuerySettings querySettings)
at System.Linq.Parallel.ForAllOperator`1.RunSynchronously()
at GitHub.Runner.Sdk.IOUtil.DeleteDirectory(String path, Boolean contentsOnly, Boolean continueOnContentDeleteError, CancellationToken cancellationToken)
at GitHub.Runner.Worker.TempDirectoryManager.CleanupTempDirectory()
[2026-02-16 17:31:43Z ERR TempDirectoryManager] #####################################################
[2026-02-16 17:31:43Z ERR TempDirectoryManager] System.UnauthorizedAccessException: Access to the path '/home/ghrunner/actions-runner/_work/_temp/_github_home/.ssh' is denied.
---> System.IO.IOException: Permission denied
--- End of inner exception stack trace ---
at System.IO.Enumeration.FileSystemEnumerator`1.Init()
at System.IO.DirectoryInfo.InternalEnumerateInfos(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
at GitHub.Runner.Sdk.IOUtil.Enumerate(DirectoryInfo directory, CancellationTokenSource tokenSource)+MoveNext()
at System.Linq.Parallel.PartitionedDataSource`1.ContiguousChunkLazyEnumerator.MoveNext(T& currentElement, Int32& currentKey)
at System.Linq.Parallel.SpoolingTaskBase.Work()
at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
[2026-02-16 17:31:43Z ERR TempDirectoryManager] #####################################################
[2026-02-16 17:31:43Z ERR TempDirectoryManager] System.IO.IOException: Permission denied
[2026-02-16 17:31:43Z INFO HostContext] Well known directory 'Bin': '/home/ghrunner/actions-runner/bin.2.331.0'
[2026-02-16 17:31:43Z INFO HostContext] Well known directory 'Root': '/home/ghrunner/actions-runner'
[2026-02-16 17:31:43Z INFO HostContext] Well known directory 'Diag': '/home/ghrunner/actions-runner/_diag'
[2026-02-16 17:31:43Z INFO HostContext] Well known config file 'Telemetry': '/home/ghrunner/actions-runner/_diag/.telemetry'
[2026-02-16 17:31:43Z INFO JobRunner] Raising job completed against run service
[2026-02-16 17:31:43Z INFO Worker] Job completed.
To Reproduce
Steps to reproduce the behavior:
- Run some jobs which create a file which can not be accessed by the service user.
- Run more jobs
- See the temp directory manager fail, and the disk fill up.
Expected behavior
Temp DirectoryManager should skip files it can not clean up, and clean up those which it has access to.
Runner Version and Platform
Version of your runner?
Ubuntu 24.04.4 running 2.331
What's not working?
action runners' temp directory is constantly growing
Job Log Output
Job log output does not indicate any issues, but jobs wait for longer and longer on the completed phase.
Runner and Worker's Diagnostic Logs
Error from logs shown at top of report, otherwise log is normal for a job.