owasp-amass/amass · warning
the context expired
Error message
the context expired
What it means
Crawl spiders a web page within a given scope, but first performs a non-blocking select on the provided context. If ctx is already done — cancelled or past its deadline — it returns 'the context expired' immediately instead of starting work. This is standard Go context propagation: the caller owns the crawl's lifetime.
Source
Thrown at internal/net/http/http.go:212
req.Header.Set("Accept-Language", AcceptLang)
for k, values := range r.Header {
for _, v := range values {
req.Header.Set(k, v)
}
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return RespToAmassResponse(resp), nil
}
// Crawl will spider the web page at the URL argument looking while staying within the scope provided.
func Crawl(ctx context.Context, u string, scope []string, max int, callback func(*Request, *Response)) error {
select {
case <-ctx.Done():
return fmt.Errorf("the context expired")
default:
}
var count int
var m sync.Mutex
filter := bf.NewDefaultStableBloomFilter(10000, 0.01)
defer filter.Reset()
attrs := []string{"action", "cite", "data", "formaction",
"href", "longdesc", "poster", "src", "srcset", "xmlns"}
tags := []string{"a", "area", "audio", "base", "blockquote", "button",
"embed", "form", "frame", "frameset", "html", "iframe", "img", "input",
"ins", "link", "noframes", "object", "q", "script", "source", "track", "video"}
g := geziyor.NewGeziyor(&geziyor.Options{
StartURLs: []string{u},
RobotsTxtDisabled: true,
UserAgent: UserAgent,
LogDisabled: true,View on GitHub (pinned to 79299dce87)
Solutions
- Increase the WithTimeout duration so it covers the expected crawl time.
- Do not pass an already-cancelled context; build a fresh one (context.Background() plus a new timeout).
- Audit upstream code for premature cancel() calls or parent contexts ending early.
- Treat the error as normal cancellation: stop work and propagate rather than retry blindly.
Example fix
// before ctx, cancel := context.WithTimeout(parent, 500*time.Millisecond) err := Crawl(ctx, url, scope, max, cb) // deadline too short -> the context expired // after ctx, cancel := context.WithTimeout(parent, 30*time.Second) err := Crawl(ctx, url, scope, max, cb)
Defensive patterns
Strategy: retry
Validate before calling
// Go — check before calling
select {
case <-ctx.Done():
return fmt.Errorf("cannot start crawl: %v", ctx.Err())
default:
} Try / catch
// Go
crawlCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := Crawl(crawlCtx, u, scope, max, cb); err != nil {
if errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), "the context expired") {
// retry with a longer deadline or back off
}
} Prevention
- Size crawl deadlines generously; crawls are long-running by nature.
- Never pass a context that may already be cancelled into Crawl.
- Use context.WithTimeout on a fresh Background context for standalone crawls.
- Treat this error as cancellation, not a bug; avoid tight retry loops without backoff.
When it happens
Trigger: Calling Crawl with a context that is already cancelled, a deadline that expired before the call, or a very short timeout (e.g. context.WithTimeout(ctx, 1*time.Millisecond)); also as in TestCrawl, where a test context expires during crawling.
Common situations: HTTP-handler parent contexts ending before slow crawls finish, test harnesses with tight deadlines, goroutine shutdown racing with crawl start.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- the Amass engine did not respond within the timeout period
- failed to establish a connection with the WHOIS server: %v
- error reading the response from the WHOIS server: %v
AI-assisted analysis of owasp-amass/amass@79299dce87 (2026-09-06).
Data as JSON: /api/errors/a0d52eb308654788.
Report an issue: GitHub.