{"record":{"id":"e72d0e40c4c7875a","repo":"cloudflare/cloudflared","slug":"failed-to-run-transfer-service","errorCode":null,"errorMessage":"failed to run transfer service","messagePattern":"failed to run transfer service","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"token/token.go","lineNumber":398,"sourceCode":"\t\t\t\treturn \"\", errors.Wrap(err, \"failed to write app token to disk\")\n\t\t\t}\n\t\t\treturn appToken, nil\n\t\t}\n\t}\n\treturn getTokensFromEdge(appURL, appInfo.AppAUD, appTokenPath, orgTokenPath, useHostOnly, autoClose, isFedramp, log)\n}\n\n// getTokensFromEdge will attempt to use the transfer service to retrieve an app and org token, save them to disk,\n// and return the app token.\nfunc getTokensFromEdge(appURL *url.URL, appAUD, appTokenPath, orgTokenPath string, useHostOnly bool, autoClose bool, isFedramp bool, log *zerolog.Logger) (string, error) {\n\t// If no org token exists or if it couldn't be exchanged for an app token, then run the transfer service flow.\n\n\t// this weird parameter is the resource name (token) and the key/value\n\t// we want to send to the transfer service. the key is token and the value\n\t// is blank (basically just the id generated in the transfer service)\n\tresourceData, err := RunTransfer(appURL, appAUD, keyName, keyName, \"\", true, useHostOnly, autoClose, isFedramp, log, appTokenPath+\".url\")\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to run transfer service\")\n\t}\n\tvar resp transferServiceResponse\n\tif err = json.Unmarshal(resourceData, &resp); err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to marshal transfer service response\")\n\t}\n\n\t// If we were able to get the auth domain and generate an org token path, lets write it to disk.\n\tif orgTokenPath != \"\" {\n\t\tif err := os.WriteFile(orgTokenPath, []byte(resp.OrgToken), 0600); err != nil {\n\t\t\treturn \"\", errors.Wrap(err, \"failed to write org token to disk\")\n\t\t}\n\t}\n\n\tif err := os.WriteFile(appTokenPath, []byte(resp.AppToken), 0600); err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to write app token to disk\")\n\t}\n\n\treturn resp.AppToken, nil","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/token/token.go#L380-L416","documentation":"getTokensFromEdge wraps this error when RunTransfer — the local transfer-service flow that mints a token by relaying through a browser/localhost transfer — returns an error. This is the fallback path used when no cached app or org token can be found or exchanged, so it commonly surfaces as an interactive login failure.","triggerScenarios":"getToken finds no usable cached tokens and calls getTokensFromEdge -> RunTransfer, which fails because the local transfer service cannot start (port binding failure), the browser login flow fails, or the edge returns an error during the transfer.","commonSituations":"Headless environments (CI, SSH-only servers) where the interactive browser flow cannot complete; localhost port conflicts blocking the transfer service; corporate proxies blocking the loopback or edge callbacks; stale/expired org token that cannot be refreshed non-interactively.","solutions":["Run `cloudflared access login <url>` interactively once on a machine with a browser to seed the org token, then copy it to the headless host","Check that the localhost port the transfer service uses is free and not blocked by firewall/proxy","Inspect the wrapped RunTransfer error for the concrete failure (port bind, edge HTTP error, browser launch)","Verify the service can reach the Cloudflare edge (no egress restrictions on the access domain)"],"exampleFix":"// headless: reuse an org token minted on an interactive machine\nscp interactive:~/.cloudflared/org-token-* headless:~/.cloudflared/\n# then re-run cloudflared access; it will exchange the org token instead of running the transfer service","handlingStrategy":"fallback","validationCode":"// headless preflight: can we reach the edge and is an org token present?\ntoks, _ := filepath.Glob(homeDir + \"/.cloudflared/org-token-*\")\nif len(toks) == 0 && !isInteractive() {\n\treturn fmt.Errorf(\"no org token cached and no browser available — run 'cloudflared access login' on an interactive host\")\n}","typeGuard":null,"tryCatchPattern":"token, err := FetchToken(...)\nif err != nil && strings.Contains(err.Error(), \"failed to run transfer service\") {\n\t// interactive flow unavailable: guide user to manual login\n\treturn fmt.Errorf(\"%w — run 'cloudflared access login <url>' once to authenticate\", err)\n}","preventionTips":["Seed org tokens on headless hosts via interactive login + file copy","Reserve the localhost transfer port; check for conflicts","Test the browser flow after proxy/firewall changes","Keep cloudflared updated to avoid transfer-service protocol drift"],"tags":["network","authentication","transfer-service","login"],"backgroundTag":"authentication-required","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}