cloudflare/cloudflared · error

failed to find Access application at %s

Error message

failed to find Access application at %s

What it means

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.

Source

Thrown at token/token.go:502

		Timeout: time.Second * 7,
	}

	req, err := http.NewRequest("HEAD", reqURL, nil)
	if err != nil {
		return "", errors.Wrap(err, "failed to create app info request")
	}
	req.Header.Set(accessMetadataReqHeader, accessMetadataReqValue)
	req.Header.Set(userAgentHeader, userAgent)

	resp, err := client.Do(req) // nolint: gosec
	if err != nil {
		return "", errors.Wrap(err, "failed to get app info")
	}
	_ = resp.Body.Close()

	rawJWT := resp.Header.Get(accessMetadataRespHeader)
	if rawJWT == "" {
		return "", fmt.Errorf("failed to find Access application at %s", reqURL)
	}
	return rawJWT, nil
}

func validateMetadataIssuedAt(iat int64, now time.Time) error {
	if iat <= 0 {
		return errors.New("metadata JWT iat is missing or invalid")
	}
	issuedAt := time.Unix(iat, 0)
	if issuedAt.Before(now.Add(-metadataMaxAge)) {
		return fmt.Errorf("metadata JWT is older than %s", metadataMaxAge)
	}
	if issuedAt.After(now.Add(metadataAllowedClockSkew)) {
		return fmt.Errorf("metadata JWT is more than %s in the future", metadataAllowedClockSkew)
	}
	return nil
}

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Confirm the URL is actually protected by a Cloudflare Access self-hosted application for that team domain.
  2. Check the URL for typos, wrong scheme, or redirects that land on a different host.
  3. Verify network egress reaches Cloudflare directly (no proxy stripping the cf-access-metadata header).
  4. Re-create or fix the Access application binding in the Zero Trust dashboard if the app was recently deleted or its domain changed.
  5. Add debug logging of resp.Header to inspect what the metadata endpoint actually returned.

Example fix

// before
rawJWT := resp.Header.Get(accessMetadataRespHeader)
// after (caller-side guard before calling GetAppInfo)
if !strings.Contains(appURL, "cloudflareaccess") && !isAccessProtected(appURL) {
    return nil, errors.New("URL is not behind Cloudflare Access; skip GetAppInfo")
}
appInfo, err := token.GetAppInfo(authDomain, appURL)
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight: check the header exists before calling GetAppInfo
resp, err := http.Get(appURL)
if err != nil { return err }
if resp.Header.Get("cf-access-metadata") == "" {
    return fmt.Errorf("%s is not behind Cloudflare Access (no cf-access-metadata header)", appURL)
}

Try / catch

appInfo, err := token.GetAppInfo(authDomain, appURL)
if err != nil {
    if strings.Contains(err.Error(), "failed to find Access application") {
        return fmt.Errorf("%w — confirm the Access app exists and covers this hostname", err)
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/305ff4ea99c8200c. Report an issue: GitHub.