Wei-Shaw/sub2api · error
ChatGPT DeviceCheck token generation timed out
Error message
ChatGPT DeviceCheck token generation timed out
What it means
The darwin provider shells out to the ChatGPT app's bundled Node runtime to produce a DeviceCheck token, with a context deadline (attestationTimeout) enforced via command.Run under runCtx. If the child process is killed by the deadline (runCtx.Err() is DeadlineExceeded), this specific timeout error is returned instead of a generic exec failure.
Source
Thrown at backend/internal/platform/liveattestation/attestation_darwin.go:123
signalsJSON, err := json.Marshal(signals)
if err != nil {
return "", fmt.Errorf("encode Live attestation signals: %w", err)
}
command := exec.CommandContext(runCtx, nodePath, "-e", deviceCheckScript)
command.Env = []string{
"PATH=/usr/bin:/bin",
"SUB2API_DEVICECHECK_MODULE=" + modulePath,
"SUB2API_ATTESTATION_BUNDLE_ID=" + bundleID,
"SUB2API_ATTESTATION_SIGNALS=" + string(signalsJSON),
}
var stdout bytes.Buffer
var stderr bytes.Buffer
command.Stdout = &stdout
command.Stderr = &stderr
if err := command.Run(); err != nil {
if errors.Is(runCtx.Err(), context.DeadlineExceeded) {
return "", errors.New("ChatGPT DeviceCheck token generation timed out")
}
reason := strings.TrimSpace(stderr.String())
if len(reason) > 240 {
reason = reason[:240]
}
if reason == "" {
reason = err.Error()
}
return "", fmt.Errorf("ChatGPT DeviceCheck token generation failed: %s", reason)
}
header := strings.TrimSpace(stdout.String())
if len(header) < 20 || len(header) > 16*1024 || !json.Valid([]byte(header)) {
return "", errors.New("ChatGPT DeviceCheck returned a malformed attestation")
}
return header, nil
}
func (p *darwinProvider) findApplication() (string, error) {View on GitHub (pinned to 073e92d171)
Solutions
- Launch the ChatGPT app once interactively to clear Gatekeeper and Keychain prompts, then retry.
- Check system load / memory pressure on the macOS host.
- Retry the request; transient subprocess hangs usually clear after the first successful run warms caches.
- If timeouts persist, profile the node invocation manually with the documented SUB2API_* env vars to see where it stalls.
Defensive patterns
Strategy: retry
Try / catch
tok, err := provider.Generate(ctx)
if err != nil && strings.Contains(err.Error(), "timed out") {
tok, err = provider.Generate(ctx) // first-run Gatekeeper/Keychain warmup is common
} Prevention
- Open the ChatGPT app once interactively to clear Gatekeeper prompts
- Monitor load on the macOS host
- Warm the attestation path at startup with a dummy Generate
When it happens
Trigger: The node subprocess hangs: first-run Gatekeeper prompts, disk pressure, the native module blocking on Keychain access, or system under heavy load such that token generation exceeds attestationTimeout.
Common situations: macOS Gatekeeper/first-launch verification of the ChatGPT app binaries; Keychain access prompts waiting for user consent; overloaded or memory-throttled servers; slept/latency-spiking disks.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- ChatGPT DeviceCheck returned a malformed attestation
- live attestation is only supported when Sub2API runs on macO
- live attestation currently requires Apple Silicon; Intel mac
- api_error
- the installed ChatGPT app has an unexpected bundle identifie
AI-assisted analysis of Wei-Shaw/sub2api@073e92d171 (2026-08-15).
Data as JSON: /api/errors/2f199be1ede4a4b0.
Report an issue: GitHub.