hashicorp/packer · error

request GitHub OIDC token: %w

Error message

request GitHub OIDC token: %w

What it means

The HTTP GET to GitHub's OIDC token endpoint failed at the transport level (client.Do returned an error) — connection refused/reset, DNS failure, TLS error, or the 30-second client timeout expired. The request never received an HTTP response.

Source

Thrown at internal/attestation/sign_keyless.go:345

	if err != nil {
		return "", fmt.Errorf("parse GitHub OIDC request URL: %w", err)
	}
	query := parsedURL.Query()
	if query.Get("audience") == "" {
		query.Set("audience", "sigstore")
		parsedURL.RawQuery = query.Encode()
	}

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, parsedURL.String(), nil)
	if err != nil {
		return "", fmt.Errorf("create GitHub OIDC request: %w", err)
	}
	req.Header.Set("Authorization", "Bearer "+requestToken)

	client := &http.Client{Timeout: 30 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("request GitHub OIDC token: %w", err)
	}
	defer func() { _ = resp.Body.Close() }()

	if resp.StatusCode/100 != 2 {
		return "", fmt.Errorf("request GitHub OIDC token: unexpected status %s", resp.Status)
	}

	var payload struct {
		Value string `json:"value"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {
		return "", fmt.Errorf("decode GitHub OIDC token response: %w", err)
	}
	return strings.TrimSpace(payload.Value), nil
}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Check the wrapped cause for timeout vs connection-refused to distinguish latency from reachability.
  2. Verify the runner can reach the OIDC endpoint (curl the URL without the bearer token to test connectivity).
  3. If behind a proxy, set HTTPS_PROXY correctly for the job.
  4. Retry the signing step — transient network blips are the most common cause.
  5. Alternatively pre-fetch the token and pass it via SIGSTORE_ID_TOKEN to skip this HTTP call.

Example fix

// before
idToken, err := resolveAmbientIDToken(ctx, env) // fails on transient network error
// after
var idToken string
var err error
for i := 0; i < 3; i++ {
    idToken, err = resolveAmbientIDToken(ctx, env)
    if err == nil {
        break
    }
    time.Sleep(2 * time.Second)
}
Defensive patterns

Strategy: retry

Validate before calling

// reachability pre-check (no auth needed)
if raw := strings.TrimSpace(env["ACTIONS_ID_TOKEN_REQUEST_URL"]); raw != "" {
    conn, err := net.DialTimeout("tcp", hostPort(raw), 5*time.Second)
    if err != nil {
        return fmt.Errorf("OIDC endpoint unreachable: %w", err)
    }
    _ = conn.Close()
}

Type guard

func errors.IsTimeoutOrNetwork(err error) bool {
    var netErr net.Error
    return errors.As(err, &netErr) || errors.Is(err, context.DeadlineExceeded)
}

Try / catch

var signer Signer
var err error
for attempt := 0; attempt < 3; attempt++ {
    signer, err = newKeylessSigner(ctx, cfg)
    if err == nil || !errors.IsTimeoutOrNetwork(err) {
        break
    }
    select {
    case <-time.After(time.Duration(1<<attempt) * time.Second):
    case <-ctx.Done():
        return ctx.Err()
    }
}

Prevention

When it happens

Trigger: resolveGitHubActionerIDToken's client.Do call fails while fetching the workflow OIDC token: unreachable ACTIONS_ID_TOKEN_REQUEST_URL host, network egress blocked in the CI job, proxy interference, or >30s latency exceeding the hardcoded http.Client timeout.

Common situations: Firewalled or air-gapped runners that block egress to the token endpoint; a misconfigured ACTIONS_ID_TOKEN_REQUEST_URL pointing at a down proxy; transient GitHub outages or slow runners hitting the 30s timeout.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/3e59d9faabc5a1f2. Report an issue: GitHub.