> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nordicfinancialnews.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Semantic search unavailable

> The 503 problem type returned when a semantic search query cannot be embedded.

<Info>
  Problem type: `https://docs.nordicfinancialnews.com/problems/semantic-unavailable`
</Info>

The API returns this problem type with HTTP `503` when a search using `mode=semantic` cannot turn your query into an embedding. Either the upstream embedding call failed, or it did not finish inside the 3 second in-request timeout.

Only requests that ask for `mode=semantic` can return this. Keyword search is unaffected and stays available throughout.

## Example response

```json theme={"dark"}
{
  "type": "https://docs.nordicfinancialnews.com/problems/semantic-unavailable",
  "title": "Semantic search unavailable",
  "status": 503,
  "detail": "The search query could not be embedded. Retry shortly — no lexical fallback is applied.",
  "instance": "urn:request:7f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c"
}
```

## Response headers

| Header        | Description                                                       |
| ------------- | ----------------------------------------------------------------- |
| `Retry-After` | Seconds to wait before retrying. This problem type sets it to `5` |

## Why you get an error instead of keyword results

When semantic matching is unavailable, the API could quietly rank your results with keyword search instead. It deliberately does not.

A silent fallback would return a differently ranked page under an identical request shape, with nothing in the response to say which ranking you received. That is difficult to detect and worse to debug, particularly for an agent that cannot tell the two apart. Failing explicitly means a `200` from a `mode=semantic` request always contains a genuine semantic result.

Choosing keyword ranking is therefore yours to make, not something the API does on your behalf.

## How to fix it

Wait the number of seconds in `Retry-After` and retry the same request. This condition is usually brief.

```python Python theme={"dark"}
import time
import requests

def semantic_search(url, params, headers, max_attempts=3):
    for attempt in range(max_attempts):
        response = requests.get(url, params=params, headers=headers)
        if response.status_code != 503:
            return response
        if attempt < max_attempts - 1:
            time.sleep(int(response.headers.get("Retry-After", 5)))

    # Semantic ranking is still unavailable. Fall back deliberately, dropping
    # mode so the request is ranked by keyword instead.
    keyword_params = {key: value for key, value in params.items() if key != "mode"}
    return requests.get(url, params=keyword_params, headers=headers)
```

If it persists past a few retries, drop `mode=semantic` and use keyword search until it recovers. Make that switch explicit in your own code so you always know which ranking produced the results you are holding.

## Retries and the embedding cache

Successful query embeddings are cached for one hour, keyed on the query text after case folding and trimming. A query that embedded successfully within the last hour is normally served from that cache, so it does not re-embed and will not raise this error.

A timed-out or failed embedding is not written to that cache, so a retry genuinely re-attempts the call rather than replaying a stored failure.

## Related

* [Error handling](/guides/errors) for the full problem type list
* [Rate limit exceeded](/problems/rate-limit-exceeded) for the `429` returned when you exceed a request limit
