actions / actions/runner

Self-hosted runner v2.336.0 fails to register — RSAFileKeyManager.GetKey() throws SerializationException

Open
#4,653 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C#
Stars
6.3k
Forks
1.4k
Avg merge
1d 16h
Merged PRs (30d)
24

Description

Symptom: On a freshly provisioned Linux VM, downloading and running actions-runner v2.336.0 (./run.sh --jitconfig <config>) fails to register deterministically, throwing:

System.Runtime.Serialization.SerializationException: Cannot add the same member twice to a SerializationInfo object

originating from RSAFileKeyManager.GetKey(). This happens on every retry, on every fresh VM of this class we've tried.

Rolling back to v2.335.1 with an otherwise-identical JIT config registers successfully every single time on the same VM class.

Investigation so far:

  • Diffed RSAFileKeyManager.cs, IRSAKeyManager.cs, IOUtil.cs, and StringUtil.cs between v2.335.1 and v2.336.0 directly from raw.githubusercontent.com — they are byte-identical. The credential file is read via Newtonsoft.Json, not the dotnet SDK's own serialization, so a dotnet-SDK version bump between these releases doesn't explain it either.
  • Runner.cs does differ: v2.336.0 adds a new cleanupLocalConfigAfter404 code path that calls configManager.DeleteLocalRunnerConfig() when a spurious TaskAgentNotFoundException/RunnerNotFoundException occurs during message polling. This path does not exist at all in v2.335.1.
  • RSAFileKeyManager.GetKey() is invoked on every OAuth token exchange (OAuthCredential.cs, MessageListener.CreateSessionAsync) throughout the runner's lifetime, not just once at startup.
  • Leading hypothesis (not confirmed via live repro): the new cleanup path racing a concurrent GetKey() read/write of the same on-disk credential file is causing the SerializationException. This would explain why it's version-specific and deterministic specifically in a fresh-VM, JIT-registration-per-job flow (as opposed to a long-lived runner registering once).

Environment: ephemeral Linux VM, fresh runner binary downloaded per job, JIT registration via --jitconfig. No newer release than v2.336.0 existed as of this investigation.

Question: has this been seen elsewhere, and is there a fix planned or already shipped past v2.336.0?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by comparing the cleanupLocalConfigAfter404 path in Runner.cs between v2.335.1 and v2.336.0, then read RSAFileKeyManager.GetKey(), OAuthCredential.cs, and MessageListener.CreateSessionAsync. Reproduce JIT registration with ./run.sh --jitconfig on both versions and determine whether concurrent credential-file cleanup explains the exception; done means the cause and a version that registers successfully are established.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, github-actions
Domain
ci-cd, devops
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.