{"record":{"id":"2f25efe071204e4a","repo":"semaphoreui/semaphore","slug":"runner-registration-failed","errorCode":null,"errorMessage":"runner registration failed","messagePattern":"runner registration failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/runners/job_pool.go","lineNumber":211,"sourceCode":"\treturn false\n}\n\nfunc (p *JobPool) hasRunningJobs() bool {\n\tfor _, j := range p.snapshotRunningJobs() {\n\t\tif !j.getStatus().IsFinished() {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc (p *JobPool) Register(configFilePath *string) (err error) {\n\n\tok := p.tryRegisterRunner(configFilePath)\n\n\tif !ok {\n\t\terr = fmt.Errorf(\"runner registration failed\")\n\t\treturn\n\t}\n\n\treturn\n}\n\nfunc (p *JobPool) Unregister() (err error) {\n\n\tif util.Config.Runner.Token == \"\" {\n\t\treturn fmt.Errorf(\"runner is not registered\")\n\t}\n\n\turl := util.Config.WebHost + \"/api/internal/runners\"\n\n\treq, err := http.NewRequest(\"DELETE\", url, nil)\n\tif err != nil {\n\t\treturn\n\t}","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/services/runners/job_pool.go#L193-L229","documentation":"JobPool.Register failed because tryRegisterRunner did not succeed in registering the runner with the Semaphore server (it retries internally and returns false on exhaustion). The message is deliberately opaque; the server response/log details during registration hold the real reason.","triggerScenarios":"Register(configFilePath) is called by registerRunner/doRunnerSetup/runRunner and tryRegisterRunner exhausts its attempts — invalid registration token, unreachable server, or the server rejecting the runner.","commonSituations":"Wrong or expired runner registration token in config; WebHost pointing to the wrong URL or wrong port; TLS/network issues between runner and server; server's registration endpoint disabled.","solutions":["Verify the runner registration token in the config is valid and not expired; regenerate it from the server UI if needed.","Check the WebHost/URL in the runner config is reachable from the runner (curl the server API).","Inspect runner logs for the underlying HTTP error from tryRegisterRunner attempts.","Confirm server version and runner version are compatible."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"resp, err := http.Get(cfg.WebHost + \"/api/internal/runners\")\nif err != nil || resp.StatusCode >= 400 {\n    return errors.New(\"server unreachable or rejecting requests before registration\")\n}","typeGuard":null,"tryCatchPattern":"if err := pool.Register(&configPath); err != nil {\n    if strings.Contains(err.Error(), \"runner registration failed\") {\n        backoff := 5 * time.Second\n        for i := 0; i < 5; i++ {\n            time.Sleep(backoff)\n            if err := pool.Register(&configPath); err == nil { break }\n            backoff *= 2\n        }\n    }\n}","preventionTips":["Verify the registration token before starting the runner.","Health-check the server URL from the runner host before launch.","Keep runner and server versions in sync."],"tags":["runner","registration","network","authentication"],"backgroundTag":"http-request-failed","analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}