{"record":{"id":"305ff4ea99c8200c","repo":"cloudflare/cloudflared","slug":"failed-to-find-access-application-at-s","errorCode":null,"errorMessage":"failed to find Access application at %s","messagePattern":"failed to find Access application at (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"token/token.go","lineNumber":502,"sourceCode":"\t\tTimeout: time.Second * 7,\n\t}\n\n\treq, err := http.NewRequest(\"HEAD\", reqURL, nil)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to create app info request\")\n\t}\n\treq.Header.Set(accessMetadataReqHeader, accessMetadataReqValue)\n\treq.Header.Set(userAgentHeader, userAgent)\n\n\tresp, err := client.Do(req) // nolint: gosec\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to get app info\")\n\t}\n\t_ = resp.Body.Close()\n\n\trawJWT := resp.Header.Get(accessMetadataRespHeader)\n\tif rawJWT == \"\" {\n\t\treturn \"\", fmt.Errorf(\"failed to find Access application at %s\", reqURL)\n\t}\n\treturn rawJWT, nil\n}\n\nfunc validateMetadataIssuedAt(iat int64, now time.Time) error {\n\tif iat <= 0 {\n\t\treturn errors.New(\"metadata JWT iat is missing or invalid\")\n\t}\n\tissuedAt := time.Unix(iat, 0)\n\tif issuedAt.Before(now.Add(-metadataMaxAge)) {\n\t\treturn fmt.Errorf(\"metadata JWT is older than %s\", metadataMaxAge)\n\t}\n\tif issuedAt.After(now.Add(metadataAllowedClockSkew)) {\n\t\treturn fmt.Errorf(\"metadata JWT is more than %s in the future\", metadataAllowedClockSkew)\n\t}\n\treturn nil\n}\n","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/token/token.go#L484-L520","documentation":"fetchMetadataJWT performs an HTTP GET to the Access metadata endpoint and expects the response to carry the raw JWT in the `cf-access-metadata` header. If the response succeeds but the header is missing or empty, it means the requested URL is not served by a Cloudflare Access application, so there is no metadata token to return; the function fails with this error naming the requested URL.","triggerScenarios":"Calling GetAppInfo (directly or through login, curl, generateToken, sshGen) when the HTTP response has no cf-access-metadata header — the hostname is not behind Cloudflare Access, the request followed redirects to a non-Access page, or the edge returned an error/HTML login page instead of metadata.","commonSituations":"Typo in the app URL or pointing at a domain with no Access application; an expired/misconfigured Access app returning a normal page; network middleboxes stripping the custom header; hitting an Access service-auth (mTLS) app that does not emit metadata for this request.","solutions":["Confirm the URL is actually protected by a Cloudflare Access self-hosted application for that team domain.","Check the URL for typos, wrong scheme, or redirects that land on a different host.","Verify network egress reaches Cloudflare directly (no proxy stripping the cf-access-metadata header).","Re-create or fix the Access application binding in the Zero Trust dashboard if the app was recently deleted or its domain changed.","Add debug logging of resp.Header to inspect what the metadata endpoint actually returned."],"exampleFix":"// before\nrawJWT := resp.Header.Get(accessMetadataRespHeader)\n// after (caller-side guard before calling GetAppInfo)\nif !strings.Contains(appURL, \"cloudflareaccess\") && !isAccessProtected(appURL) {\n    return nil, errors.New(\"URL is not behind Cloudflare Access; skip GetAppInfo\")\n}\nappInfo, err := token.GetAppInfo(authDomain, appURL)","handlingStrategy":"validation","validationCode":"// pre-flight: check the header exists before calling GetAppInfo\nresp, err := http.Get(appURL)\nif err != nil { return err }\nif resp.Header.Get(\"cf-access-metadata\") == \"\" {\n    return fmt.Errorf(\"%s is not behind Cloudflare Access (no cf-access-metadata header)\", appURL)\n}","typeGuard":null,"tryCatchPattern":"appInfo, err := token.GetAppInfo(authDomain, appURL)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to find Access application\") {\n        return fmt.Errorf(\"%w — confirm the Access app exists and covers this hostname\", err)\n    }\n    return err\n}","preventionTips":["Verify the hostname in the Cloudflare Zero Trust dashboard is bound to a self-hosted Access application.","Avoid proxies/interceptors that strip custom response headers like cf-access-metadata.","Watch for redirects: the final URL must still be the Access-protected host.","Test with `cloudflared access curl <url>` first to confirm Access serves the hostname."],"tags":["http","cloudflare-access","jwt","network"],"backgroundTag":"empty-api-response","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"}