dagger/dagger · error

failed to fetch OIDC token from %s server responded with %s

Error message

failed to fetch OIDC token from %s server responded with %s

What it means

Returned when the Dagger Cloud OIDC endpoint responds with a non-200 status. Note the check compares res.StatusCode (the earlier GitHub token response) rather than loginRes.StatusCode, but reports the Dagger endpoint (reqURL) and its status (loginRes.Status) in the message.

Source

Thrown at internal/cloud/auth/auth.go:388

		if err := json.NewEncoder(b).Encode(payload); err != nil {
			return nil, fmt.Errorf("failed to encode OIDC payload: %w", err)
		}
		reqURL := apiURL + "/v1/oidc?provider=github"
		r, err = http.NewRequestWithContext(ctx, http.MethodPost, reqURL, b)
		if err != nil {
			return nil, fmt.Errorf("failed to create request on %s for fetching OIDC token: %w", reqURL, err)
		}
		r.Header.Set("Authorization", "Bearer "+providerToken)
		r.Header.Set("Content-Type", "application/json")

		loginRes, err := http.DefaultClient.Do(r)
		if err != nil {
			return nil, fmt.Errorf("failed to request OIDC token at %s: %w", reqURL, err)
		}
		defer loginRes.Body.Close()

		if res.StatusCode != http.StatusOK {
			return nil, fmt.Errorf("failed to fetch OIDC token from %s server responded with %s", reqURL, loginRes.Status)
		}

		tokenResponse := &oidcTokenResponse{}
		if err := json.NewDecoder(loginRes.Body).Decode(&tokenResponse); err != nil {
			return nil, fmt.Errorf("failed to decode OIDC token response from %s: %w", reqURL, err)
		}
		return tokenResponse, nil
	}

	return nil, fmt.Errorf("OIDC authentication is not supported in this context, please use a DAGGER_CLOUD_TOKEN or 'dagger login'")
}

func GetCloudAuth(ctx context.Context) (*Cloud, error) {
	var auth *Cloud
	if dct := os.Getenv("DAGGER_CLOUD_TOKEN"); len(dct) > 0 {
		// OIDC is a special case within DAGGER_CLOUD_TOKEN
		if dct == "oidc" {
			t, err := fetchOIDCAuth(ctx)

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Check loginRes.Status in the message: 401/403 means the OIDC token was rejected — confirm your GitHub org/repo is registered with Dagger Cloud
  2. Verify the GitHub workflow has permissions: id-token: write
  3. Confirm the audience (dagger.cloud) matches what the server expects
  4. If the underlying problem is res (the GitHub response) non-200, check the GitHub id-token request status first

Example fix

// before
if res.StatusCode != http.StatusOK {
    return nil, fmt.Errorf("failed to fetch OIDC token from %s server responded with %s", reqURL, loginRes.Status)
}
// after
if loginRes.StatusCode != http.StatusOK {
    body, _ := io.ReadAll(loginRes.Body)
    return nil, fmt.Errorf("failed to fetch OIDC token from %s server responded with %s: %s", reqURL, loginRes.Status, body)
}
Defensive patterns

Strategy: fallback

Validate before calling

// after receiving the response, before treating it as success:
if loginRes.StatusCode != http.StatusOK {
    body, _ := io.ReadAll(loginRes.Body)
    return fmt.Errorf("oidc endpoint %s: %s (%s)", reqURL, loginRes.Status, body)
}

Try / catch

if loginRes.StatusCode != http.StatusOK {
    body, _ := io.ReadAll(loginRes.Body)
    return nil, fmt.Errorf("failed to fetch OIDC token from %s server responded with %s: %s", reqURL, loginRes.Status, body)
}
// fallback: use DAGGER_CLOUD_TOKEN auth instead of OIDC

Prevention

When it happens

Trigger: The POST to /v1/oidc returned 401/403/4xx/5xx — typically the GitHub OIDC token was rejected (expired, wrong audience, job not in an allowed org), or the Dagger Cloud API errored. Also fires when the earlier GitHub request's status was non-200 but its body still parsed.

Common situations: GitHub workflow's OIDC token issued for an org not registered with Dagger Cloud; ACTIONS_ID_TOKEN audience mismatch; expired/short-lived OIDC token; Dagger Cloud server error.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/01dd32a95b3a301e. Report an issue: GitHub.