Nominatim returns 404 if started after PostgreSQL
Describe the bug
Nominatim silently breaks if PostgreSQL isn't available during startup. The search endpoint returns 404 for all requests. There's also no error reported in the output of gunicorn:
[2025-06-05 12:53:09 +0200] [7] [INFO] Starting gunicorn 23.0.0
[2025-06-05 12:53:09 +0200] [7] [INFO] Listening at: unix:/run/nominatim.sock (7)
[2025-06-05 12:53:09 +0200] [7] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2025-06-05 12:53:09 +0200] [105] [INFO] Booting worker with pid: 105
[2025-06-05 12:53:09 +0200] [107] [INFO] Booting worker with pid: 107
[2025-06-05 12:53:09 +0200] [109] [INFO] Booting worker with pid: 109
[2025-06-05 12:53:09 +0200] [114] [INFO] Booting worker with pid: 114
[2025-06-05 12:53:09 +0200] [105] [INFO] Started server process [105]
[2025-06-05 12:53:09 +0200] [105] [INFO] Waiting for application startup.
[2025-06-05 12:53:09 +0200] [105] [INFO] Application startup complete.
[2025-06-05 12:53:09 +0200] [107] [INFO] Started server process [107]
[2025-06-05 12:53:09 +0200] [107] [INFO] Waiting for application startup.
[2025-06-05 12:53:09 +0200] [107] [INFO] Application startup complete.
[2025-06-05 12:53:09 +0200] [109] [INFO] Started server process [109]
[2025-06-05 12:53:09 +0200] [109] [INFO] Waiting for application startup.
[2025-06-05 12:53:09 +0200] [109] [INFO] Application startup complete.
[2025-06-05 12:53:09 +0200] [114] [INFO] Started server process [114]
[2025-06-05 12:53:09 +0200] [114] [INFO] Waiting for application startup.
[2025-06-05 12:53:09 +0200] [114] [INFO] Application startup complete.
To Reproduce
- Start Nominatim
- Start PostgreSQL
- Check
/statuswhich returnsOK - Any search will return
{"title": "404 Not Found"}
Either Nominatim should recover from this state once PostgreSQL is available, or it should properly report that it is broken via the /status endpoint, along with some error logging.
The API will recover when Postgresql is not running yet. You can see that /reverse will work fine, once Postgres is up and running. The issue here is that the API checks if the database is in reverse-only mode by looking for the search_name table. Given that it can't find it, when PostgreSQL isn't up and running, it disables the endpoint and that's what you get.
We can have status return a list of available endpoints in the json format. You can check if search is up and running from there. Would that be sufficient? I really don't see how to recover the search endpoint otherwise in a way that doesn't add overhead for normal operations.
The issue here is that the API checks if the database is in reverse-only mode by looking for the search_name table. Given that it can't find it, when PostgreSQL isn't up and running, it disables the endpoint and that's what you get.
Can we modify that check instead? A connection error shouldn't equate to "table doesn't exist" IMHO.
In essence:
- Postgres available + table exists -> regular mode
- Postgres unavailable -> regular mode
- Postgres available + table doesn't exist -> reverse-only mode
It would be even better if the reverse-only mode would be a configuration setting e.g. NOMINATIM_REVERSE_ONLY
That would just open up the same problem you are reporting now for reverse only mode. Not exactly an improvement.
It would be even better if the reverse-only mode would be a configuration setting e.g.
NOMINATIM_REVERSE_ONLY
I'm quoting myself because I was a bit late with the edit 😅
The check is the way it is because a missing search_name table causes internal server errors for the search endpoint. A configuration setting is less reliable for avoiding the internal server error.
I guess an extended status endpoint would be the cleanest solution than 👍