owasp-amass/amass · error

GLEIFSearchFuzzyCompletions: %s

Error message

GLEIFSearchFuzzyCompletions: %s

What it means

GLEIFSearchFuzzyCompletions queries the GLEIF API for fuzzy-completion LEI records matching a name. It wraps any failure to fetch or read the HTTP response body into this error, preserving the underlying cause and the queried name. The plugin cannot proceed without the LEI data, so it returns a hard error instead of partial results.

Source

Thrown at engine/plugins/api/gleif/gleif.go:41

func init() {
	limit := rate.Every(3 * time.Second)

	gleifLimit = rate.NewLimiter(limit, 1)
}

// GLEIFSearchFuzzyCompletions performs the fuzzy completion search for the given name.
func GLEIFSearchFuzzyCompletions(ctx context.Context, name string) (*FuzzyCompletionsResponse, error) {
	u := "https://api.gleif.org/api/v1/fuzzycompletions?field=entity.legalName&q=" + url.QueryEscape(name)

	_ = gleifLimit.Wait(ctx)
	wctx, cancel := context.WithTimeout(ctx, 60*time.Second)
	defer cancel()

	resp, err := amasshttp.RequestWebPage(wctx, amasshttp.DefaultClient, &amasshttp.Request{URL: u})
	if err != nil || resp.Body == "" {
		msg := fmt.Sprintf("Failed to obtain the LEI record for %s: %s", name, err)
		return nil, fmt.Errorf("GLEIFSearchFuzzyCompletions: %s", msg)
	}

	var result FuzzyCompletionsResponse
	if err := json.Unmarshal([]byte(resp.Body), &result); err != nil {
		msg := fmt.Sprintf("Failed to unmarshal the LEI record for %s: %s", name, err)
		return nil, fmt.Errorf("GLEIFSearchFuzzyCompletions: %s", msg)
	} else if len(result.Data) == 0 {
		return nil, fmt.Errorf("GLEIFSearchFuzzyCompletions: no results found")
	}

	return &result, nil
}

// GLEIFGetLEIRecord retrieves the LEI record for the given identifier.
func GLEIFGetLEIRecord(ctx context.Context, id string) (*LEIRecord, error) {
	u := "https://api.gleif.org/api/v1/lei-records/" + id

	_ = gleifLimit.Wait(ctx)

View on GitHub (pinned to 79299dce87)

Solutions

  1. Check network connectivity to https://api.gleif.org from the host running the scan (curl the URL directly).
  2. Retry the lookup; transient network failures are common, and the request already uses a 60s timeout.
  3. Verify proxy/firewall rules allow HTTPS egress to api.gleif.org.
  4. Inspect the wrapped cause in msg (logged with the error) to distinguish timeout vs DNS vs empty-body and address that specific cause.
  5. Implement a fallback to the non-fuzzy GLEIF search endpoint if fuzzy completions repeatedly fail.

Example fix

// before
resp, err := amasshttp.RequestWebPage(wctx, amasshttp.DefaultClient, &amasshttp.Request{URL: u})
if err != nil || resp.Body == "" {
	return nil, fmt.Errorf("GLEIFSearchFuzzyCompletions: %s", msg)
}
// after
resp, err := amasshttp.RequestWebPage(wctx, amasshttp.DefaultClient, &amasshttp.Request{URL: u})
if err != nil {
	return nil, fmt.Errorf("GLEIFSearchFuzzyCompletions: %w", err) // caller can errors.Is/As on the cause and retry
}
if resp.Body == "" {
	return nil, fmt.Errorf("GLEIFSearchFuzzyCompletions: empty response body")
}
Defensive patterns

Strategy: try-catch

Validate before calling

url := "https://api.gleif.org/api/v1/fuzzy_completions?q=" + name
if resp, err := http.Head(url); err != nil || resp.StatusCode != http.StatusOK {
	// skip GLEIF source this round
}

Type guard

if resp == nil || resp.Body == "" {
	return fmt.Errorf("empty GLEIF response")
}

Try / catch

result, err := GLEIFSearchFuzzyCompletions(ctx, name)
if err != nil {
	var netErr net.Error
	if errors.As(err, &netErr) && netErr.Timeout() {
		// retry with backoff
	} else {
		// continue without GLEIF data
	}
}

Prevention

When it happens

Trigger: amasshttp.RequestWebPage returns a non-nil err (DNS failure, TLS error, timeout after the 60s wctx deadline, connection refused) or returns a response with an empty Body (e.g., HTTP error status with no payload) when called with the GLEIF fuzzy-completions URL for a given name.

Common situations: Offline or air-gapped environments; corporate proxies blocking api.gleif.org; GLEIF API rate limiting or outage returning empty bodies; transient network drops during long scans; DNS resolution failures in containers.

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 owasp-amass/amass@79299dce87 (2026-09-06). Data as JSON: /api/errors/d8788c4c6a0a86d6. Report an issue: GitHub.