SSD Nodes Learn 🎉 VPS $5.50/महिन्यापासून
मार्गदर्शक Matt Connorद्वारे Matt Connor

SearXNG मध्ये 429 त्रुटी कशी दुरुस्त करावी

SearXNG मधील 429 त्रुटी local limiter मुळे आहे की search engine ने server IP block केल्यामुळे, हे log मधील संदेशांवरून ओळखा आणि योग्य उपाय करा.

SearXNG 429 त्रुटी का परत करतो

Self-hosted SearXNG instance दोन असंबंधित कारणांमुळे 429 त्रुटी परत करतो. तुम्हाला दुरुस्त करावा लागणारा rate limit सहसा तुम्ही गृहीत धरलेला नसतो. पहिले कारण स्थानिक आहे: SearXNG च्या स्वतःच्या limiter ने विनंती bot कडून आल्याचे ठरवले आणि Too Many Requests ला status 429 सह उत्तर दिले. दुसरे कारण upstream आहे: एखाद्या search engine ने तुमच्या server चा IP address नाकारला. त्यामुळे तुमच्या वापरकर्त्यांना 429 ऐवजी काही परिणाम नसलेले results page दिसते.

या दोन प्रकरणांसाठी उपाय वेगवेगळे आहेत. Limiter तुमच्या नियंत्रणात आहे, त्यामुळे तुम्ही तो बदलू शकता. Upstream blocking Google च्या बाजूने होते. त्यामुळे तुमच्या settings.yml मधील कोणताही बदल ते दूर करणार नाही. सुमारे एका मिनिटात log वरून कोणते प्रकरण आहे हे समजते. त्यामुळे तिथून सुरुवात करा.

या मार्गदर्शकात तुमच्या स्वतःच्या VPS वर self-hosted SearXNG instance साठी वर्णन केलेली container install गृहीत धरली आहे. खालील प्रत्येक setting name current upstream documentation आणि source मधून घेतले आहे. त्यांची August 2026 मध्ये पडताळणी केली आहे.

सेटिंग बदलण्यापूर्वी log वाचा

log window उघडी ठेवून समस्या पुन्हा निर्माण करा.

cd ./searxng/
docker compose logs -f searxng-core

Limiter चे संदेश searx.limiter नावाच्या logger कडून येतात आणि त्यात IP address दिलेला असतो. Blocklist hit मध्ये BLOCK 203.0.113.10: matched BLOCKLIST दिसते, तर allowlist hit मध्ये PASS 203.0.113.10: matched PASSLIST दिसते. Limiter ला counter store शी संपर्क साधता आला नाही, तर log मध्ये The limiter requires Valkey, please consult the documentation दिसते. याचा अर्थ कोणत्याही गोष्टीची गणना होत नाही.

प्रत्येक bot check ची नोंद debug level वर केली जाते. त्यामुळे ती नोंद default स्वरूपात दिसणार नाही. settings.yml मध्ये एका चाचणीसाठी debug सुरू करा:

general:
  debug: true

त्यानंतर log मध्ये client network जवळ NOT OK (http_accept_language) या नमुन्यासारख्या ओळी जोडल्या जातात. त्या अयशस्वी झालेला check सांगतात. चाचणीनंतर debug पुन्हा बंद करा. Deployed instance debug सुरू ठेवून चालवू नये, असे upstream मध्ये सांगितले आहे.

Engine failure यापेक्षा पूर्णपणे वेगळे दिसतात. त्यात IP ऐवजी engine चे नाव दिलेले असते. सर्वात सामान्य failure म्हणजे timeout:

HTTP requests timeout (search duration : 3.1 s, timeout: 3.0 s)

यासाठी एक page देखील आहे. enable_metrics हे true या default मूल्यावर असल्यास, तुमचा instance engine errors ची नोंद /stats/errors येथे करतो. सध्या कोणते engines उत्तर देत आहेत, हे /preferences मध्ये दिलेले असते. /stats/errors भरलेले असेल आणि log मध्ये searx.limiter ओळी नसतील, तर समस्या limiter मध्ये नाही.

काहीही debug करण्यापूर्वी version निश्चित करा

Upstream container setup दोन files मध्ये आहे.

mkdir -p ./searxng/core-config/
cd ./searxng/

curl -fsSL \
    -O https://raw.githubusercontent.com/searxng/searxng/master/container/docker-compose.yml \
    -O https://raw.githubusercontent.com/searxng/searxng/master/container/.env.example

cp -i .env.example .env

Compose file docker.io/searxng/searxng:${SEARXNG_VERSION:-latest} pull करते. Variable unset असल्यास latest मिळते. latest मुळे पुढील docker compose pull मध्ये instance तुमच्या नियंत्रणाबाहेर बदलते. त्यामुळे मागील आठवड्यात कार्यरत असलेली setting ती वाचणाऱ्या code शी जुळेनाशी होऊ शकते. SearXNG tags मध्ये date आणि commit असतात. August 2026 पर्यंत upstream .env.example मधील example tag 2026.3.25-541c6c3cb आहे. त्यामुळे .env मध्ये प्रत्यक्ष version set करा:

SEARXNG_VERSION=2026.3.25-541c6c3cb

Published tags तपासा आणि तुम्ही प्रत्यक्ष test केलेला release pin करा. त्यानंतर fixed target विरुद्ध debug करा. त्याच .env file मध्ये तुमची secret key असते. त्यामुळे तो directory कुठेही commit करण्यापूर्वी Docker Compose मध्ये env files आणि secrets कसे कार्य करतात ते वाचा.

लिमिटरला Valkey आवश्यक आहे; त्याशिवाय तो चालत नाही

लिमिटर प्रत्येक क्लायंटच्या विनंत्या मोजतो. ही मोजणी worker processes मध्ये सामायिक करावी लागते. हा store Redis चा maintained fork असलेला Valkey आहे. जुन्या SearXNG मार्गदर्शकांमध्ये या setting ला redis: म्हटले आहे. Current releases valkey: वाचतात. त्यामुळे जुन्या post मधून नव्हे, तर current documentation मधून key name कॉपी करा.

use_default_settings: true
server:
  secret_key: "change-this-value"
  limiter: true
  public_instance: false
valkey:
  url: valkey://searxng-valkey:6379/0

Upstream compose file आधीच docker.io/valkey/valkey:9-alpine image वर searxng-valkey service चालवते. त्यामुळे तो host name compose network मध्ये resolve होतो. हेच value SEARXNG_VALKEY_URL environment variable वापरूनही सेट करता येते. SearXNG आणि Valkey एकाच host वर असतील, तर Unix socket URL (unix:///path/to/socket.sock?db=0) देखील कार्य करते.

Store उपलब्ध नसताना काय होते, हे आणखी एका key वर अवलंबून असते. public_instance: false असल्यास, limiter Valkey error log मध्ये नोंदवतो आणि थांबतो. त्यामुळे instance कोणतेही rate limiting न करता सेवा देत राहते. public_instance: true असल्यास, process त्याऐवजी sys.exit(1) कॉल करतो. कारण bot protection बिघडलेल्या open instance कडून एका दिवसात प्रत्येक engine कडून CAPTCHAs (completely automated public turing test to tell computers and humans apart) गोळा केली जातात. public_instance: true सेट केल्यानंतर लगेच loop मध्ये restart होणारा container हेच दर्शवतो. प्रत्येक exit पूर्वीची शेवटची line Valkey चे नाव देते.

प्रतिबंधक प्रत्यक्षात काय मोजतो

ChartSearXNG limiter: requests allowed per client IP, defaults in ip_limit.py
The data behind this chart
[
  {
    "label": "Burst, normal client",
    "max_requests": 15,
    "window": "20 seconds"
  },
  {
    "label": "Burst, flagged client",
    "max_requests": 2,
    "window": "20 seconds"
  },
  {
    "label": "Sustained, normal client",
    "max_requests": 150,
    "window": "10 minutes"
  },
  {
    "label": "Sustained, flagged client",
    "max_requests": 10,
    "window": "10 minutes"
  },
  {
    "label": "Any non-HTML format",
    "max_requests": 4,
    "window": "1 hour"
  },
  {
    "label": "Flagged requests before block",
    "max_requests": 3,
    "window": "30 days"
  }
]

सामान्य client ला 20 सेकंदांच्या burst window मध्ये 15 requests आणि 10 मिनिटांच्या window मध्ये 150 requests करता येतात. एखादी request संशयास्पद म्हणून चिन्हांकित झाल्यावर, त्याच client साठी प्रत्येक burst window मधील मर्यादा 2 requests इतकी होते. शेवटची ओळ सर्वात कठोर आहे: 30 दिवसांच्या window मध्ये 3 संशयास्पद requests झाल्यानंतर तो address search करण्याऐवजी start page कडे redirect केला जातो आणि log मध्ये BLOCK: too many request from ... in SUSPICIOUS_IP_WINDOW (redirect to /) असे लिहिले जाते.

ही संख्या searx/botdetection/ip_limit.py मधील constants आहेत. त्या settings नाहीत आणि limiter.toml त्या उघड करत नाही. त्यामुळे त्या बदलण्यासाठी source संपादित करावा लागतो. /etc/searxng/limiter.toml मधून client चे गट तयार करण्यासाठी वापरले जाणारे address prefixes, trusted proxies ची यादी, optional link token check आणि pass तथा block lists नियंत्रित करता येतात.

Header checks मुळे request संशयास्पद म्हणून चिन्हांकित होते. प्रत्येक check चे नाव debug log मध्ये दिसते:

  • http_accept: Accept header मध्ये text/html नाही.
  • http_accept_encoding: Accept-Encoding header मध्ये gzip किंवा deflate यांपैकी एकही नाव नाही.
  • http_accept_language: Accept-Language header नाही.
  • http_connection: Connection header ची value close आहे.
  • http_user_agent: User-Agent अनुपलब्ध आहे किंवा ज्ञात bot pattern शी जुळतो.
  • http_sec_fetch: Sec-Fetch-Mode किंवा Sec-Fetch-Dest header browser कडून पाठवला जाणारा अपेक्षित header नाही.

Browser हे सर्व headers पाठवतो. साधी curl call यांपैकी जवळजवळ कोणताही header पाठवत नाही. त्यामुळे manually लिहिलेली test request पहिल्याच प्रयत्नात चिन्हांकित होते, पण तीच search browser tab मध्ये यशस्वी होते. म्हणून "माझ्या browser मध्ये ते चालते, पण माझ्या script ला 429 मिळतो" हा गूढ परिणाम नसून नेहमीचा परिणाम आहे.

Reverse proxy मागे limiter सर्वांना एकाच वेळी ब्लॉक करतो

कार्यरत instance बिघडवण्याचा हा सर्वात सामान्य मार्ग आहे. SearXNG X-Forwarded-For मधील पहिला untrusted IP client address म्हणून घेतो. तो उपलब्ध नसल्यास X-Real-IP वापरतो. तेही उपलब्ध नसल्यास connection उघडणारा address वापरतो. या headers वर विश्वास ठेवायचा की नाही हे limiter.toml मधील trusted_proxies ठरवते.

तुमच्या proxy चा address त्या यादीत नसेल, तर headers दुर्लक्षित केले जातात आणि प्रत्येक visitor proxy च्या address सह येतो. त्यामुळे सर्वजण एकच counter share करतात. 10 minutes मध्ये एकूण requests ची संख्या 150 पेक्षा जास्त झाली की संपूर्ण site एकत्रितपणे block होते. एखादा user results page काही वेळा reload केला तरी त्याच्यासोबत सर्व users ची सेवा बंद होऊ शकते.

अतिविश्वास ठेवणे अधिक धोकादायक आहे. Public range यादीत असल्यास, कोणताही visitor स्वतःचा X-Forwarded-For header पाठवून प्रत्येक request साठी नवीन identity निवडू शकतो. हे करून limiter बंद करता येतो. तुमचा स्वतःचा proxy ज्या address वरून connect होतो तोच address यादीत ठेवा. Docker मध्ये तो सहसा 172.16.0.0/12 मधील bridge network असतो. ती ओळ default configuration मध्ये comment केलेली असते.

[botdetection]
ipv4_prefix = 32
ipv6_prefix = 48

trusted_proxies = [
  '127.0.0.0/8',
  '::1',
  '172.16.0.0/12',
]

Proxy ने हे headers पाठवणेही आवश्यक आहे. Nginx त्यापैकी कोणताही header स्वतःहून जोडत नाही:

location / {
    proxy_pass http://127.0.0.1:8080;

    proxy_set_header Host              $host;
    proxy_set_header Connection        $http_connection;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
}

Caddy आणि Traefik forwarded headers आपोआप सेट करतात. त्यामुळे त्यांच्यासोबत तुम्हाला फक्त trusted_proxies या कामाचा भाग करावा लागतो. यातील trade-offs self-hosted service साठी reverse proxy निवडणे येथे स्पष्ट केले आहेत. दोन्हीपैकी कोणतेही setup तपासण्यासाठी debug सुरू करा, mobile data वापरून फोनवरून एकदा search करा आणि log line मधील network हा proxy च्या address ऐवजी तुमच्या फोनचा address असल्याची खात्री करा.

तुमच्या agent ला दर तासाला चार API requests मिळतात

JSON output default ने disabled असतो. त्यामुळे तो agent साठी enable करावा लागतो:

search:
  formats:
    - html
    - json

आता chart मधील row पुन्हा वाचा. HTML व्यतिरिक्त कोणताही format मागणारी प्रत्येक request तिच्या स्वतंत्र window मध्ये मोजली जाते: 4 requests प्रति 1 hour, प्रति address. Research agent एका task मध्ये ही मर्यादा संपवतो. त्यानंतरची प्रत्येक call 429 परत करते. ही limit वाढवता येत नाही, कारण ही संख्या source मध्ये निश्चित केलेली आहे.

योग्य उपाय म्हणजे हा client अनोळखी नाही, असे limiter ला सांगणे. त्याचा address limiter.toml मधील pass list मध्ये जोडा:

[botdetection.ip_lists]
block_ip = []

pass_ip = [
  '10.8.0.0/24',
]

pass_searxng_org = true

pass_ip ला इतर सर्व पद्धतींपेक्षा priority आहे. त्यामुळे allowlisted client header checks देखील वगळतो आणि साधी curl call कार्य करते. Range शक्य तितकी लहान ठेवा. Routable network पेक्षा VPN subnet किंवा container network ला प्राधान्य द्या. दुसरा योग्य उपाय म्हणजे agent ला public path पासून पूर्णपणे दूर ठेवणे. त्याला internal network वरील container address कडे point करा. त्या ठिकाणी proxy आणि त्याचा limiter हा traffic पाहतच नाही. ही रचना AI agent साठी SearXNG search skill देणे येथे स्पष्ट केली आहे.

टाळायचा पर्याय म्हणजे दुसऱ्या व्यक्तीने चालवलेल्या public instance कडे agent ला point करणे. Upstream engines कडून volunteer चा IP address block होण्याचा हा सर्वात जलद मार्ग आहे. JSON format default ने disabled ठेवण्याचे हेच कारण आहे.

इंजिनऐवजी ते तुम्हाला अडवत असतील

ChartHow long SearXNG suspends an engine, search.suspended_times defaults
The data behind this chart
[
  {
    "label": "SearxEngineTooManyRequests",
    "suspended_seconds": 3600,
    "roughly": "1 hour"
  },
  {
    "label": "SearxEngineAccessDenied",
    "suspended_seconds": 86400,
    "roughly": "1 day"
  },
  {
    "label": "SearxEngineCaptcha",
    "suspended_seconds": 86400,
    "roughly": "1 day"
  },
  {
    "label": "recaptcha_SearxEngineCaptcha",
    "suspended_seconds": 604800,
    "roughly": "7 days"
  },
  {
    "label": "cf_SearxEngineCaptcha",
    "suspended_seconds": 1296000,
    "roughly": "15 days"
  }
]

एखादे इंजिन स्वतःचा 429 प्रतिसाद किंवा CAPTCHA पृष्ठ पाठवते तेव्हा SearXNG नावाचा exception निर्माण करते आणि काही काळ त्या इंजिनला पुन्हा विनंत्या पाठवत नाही. Too-many-requests प्रतिसाद मिळाल्यास ते इंजिन 3600 सेकंदांसाठी suspend केले जाते. साधा CAPTCHA किंवा access-denied प्रतिसाद मिळाल्यास ते इंजिन 1 day साठी suspend केले जाते. Cloudflare मार्फत CAPTCHA दिल्यास ते इंजिन 15 days साठी suspend केले जाते. ही यादीतील सर्वात मोठी default कालमर्यादा आहे, कारण हा प्रतिसाद block edge स्तरावर असल्याचे दर्शवतो आणि पुन्हा प्रयत्न केल्याने उपयोग होणार नाही.

सामान्य अपयशांसाठी वेगळी settings वापरली जातात. Timeout किंवा parse error आल्यास search.ban_time_on_fail वरून ठरवलेल्या अल्प कालावधीसाठी इंजिन suspend केले जाते. search.ban_time_on_fail चे default मूल्य 5 seconds आहे आणि search.max_ban_time_on_fail ते 120 seconds पर्यंत मर्यादित ठेवते. त्यामुळे धीमे इंजिन काही मिनिटांत आपोआप पुन्हा उपलब्ध होते, तर blocked इंजिन अनेक तास अनुपलब्ध राहते. यामुळे लोक सांगतात ते random वाटणारे लक्षण स्पष्ट होते: सुरुवातीला results व्यवस्थित मिळतात, आणि नंतर दुपारच्या उर्वरित वेळेसाठी एका इंजिनचे results दिसेनासे होतात.

कोणावर दोष देण्यापूर्वी timeouts दुरुस्त करणे योग्य आहे. request_timeout चे default मूल्य 2.0 seconds आहे. एखाद्या engine च्या जवळच्या edge server पासून दूर असलेल्या छोट्या VPS साठी ही मर्यादा कमी आहे.

outgoing:
  request_timeout: 3.0
  max_request_timeout: 10.0
engines:
  - name: bing
    timeout: 5.0

request_timeout हे प्रत्येक engine साठी default आहे, max_request_timeout ही कमाल मर्यादा आहे आणि एखाद्या engine साठी स्वतंत्र timeout ठेवता येते. ही values वाढवल्यास page latency वाढते, पण failures कमी होतात. त्यामुळे त्या अर्ध्या seconds ने वाढवा आणि थेट 10 वर जाण्याऐवजी /stats/errors निरीक्षण करा.

एखादे engine तुमचा address खरोखर block करत असेल, तर ते काढून टाका. प्रत्येक search साठी सर्वात धीम्या engine ची वाट पाहावी लागते. त्यामुळे कायम suspend असलेले engine ठेवले तर latency वाढते आणि कोणतेही results मिळत नाहीत.

use_default_settings:
  engines:
    remove:
      - google

docker compose restart searxng-core वापरून बदल लागू करा. त्यानंतर काही searches चालवा आणि /stats/errors पुन्हा load करा. प्रत्यक्ष वापराच्या पाच minutes नंतर page रिकामे दिसत नसेल, तर बदल यशस्वी झाला आहे.

डेटासेंटरचा IP bot म्हणून मानला जाईल

तुमचा VPS पत्ता hosting range चा भाग आहे. मोठी search engines अशा ranges ना automation म्हणून रेट करतात. काही engines अशा पत्त्यावरून येणाऱ्या प्रत्येक request साठी CAPTCHA दाखवतात. Headers कितीही योग्य असले किंवा request चा वेग कितीही कमी असला, तरी हा निर्णय बदलत नाही. settings.yml मधील कोणतीही setting हे मूल्यांकन बदलत नाही.

तुम्ही कोणत्या engines कडे विनंत्या पाठवायच्या आणि तुमचे instance सार्वजनिकरीत्या सूचीबद्ध आहे का, हे बदलू शकता. एका कुटुंबाकडून वापरले जाणारे private instance सहसा कोणतीही अडचण निर्माण करत नाही. Hosting IP वरचे public instance सर्वात कडक engines कडून suspensions मिळवत राहील. तुमच्या config मधील दोषाऐवजी हे software चे सामान्य वर्तन आहे. SearXNG outgoing.proxies किंवा outgoing.using_tor_proxy वापरून engine requests proxy मार्फत पाठवू शकते. त्यामुळे traffic वेगळ्या पत्त्यावरून जाईल. Exit nodes आणि स्वस्त proxy pools यांना hosting ranges पेक्षा अधिक खराब score दिला जातो. त्यामुळे हा बदल केल्यास results खराब होण्याची शक्यता आहे.

इन्स्टन्सवर लक्ष ठेवा, म्हणजे समस्या प्रथम तुमच्या लक्षात येईल

सर्व engines suspend केलेले असतानाही SearXNG त्याच्या port वर उत्तर देते. त्यामुळे केवळ status code तपासणारी uptime check हिरवी राहते, पण इन्स्टन्स कोणताही प्रतिसाद देत नाही. त्याऐवजी content तपासा: प्रत्यक्ष search request पाठवा आणि response body मध्ये अपेक्षित असलेला एखादा शब्द आहे का ते जुळवा. Uptime Kuma keyword monitoring हे कोणतेही अतिरिक्त tooling न वापरता नेमके तेच करते. प्रत्येक version bump नंतर /stats/errors वरही लक्ष ठेवा, कारण engines चे HTML बदलते आणि rate limit मुळे नव्हे, तरी parser मध्ये बिघाड होऊ शकतो.

FAQ

SearXNG ला reverse proxy मागे ठेवल्यानंतर प्रत्येक visitor ला 429 का मिळतो?

कारण limiter proxy ला client म्हणून मोजत आहे. Connecting address X-Forwarded-For मधील trusted_proxies मध्ये /etc/searxng/limiter.toml म्हणून सूचीबद्ध असेल, तरच SearXNG ते वाचते. तो address सूचीबद्ध नसल्यास, प्रत्येक visitor एकच counter share करतो आणि सर्वजण मिळून 10 मिनिटांत 150 requests ची मर्यादा ओलांडतात. तुमचा proxy ज्या address वरून connect होतो तो address जोडा. Docker मध्ये तो सहसा bridge range 172.16.0.0/12 असतो. तसेच proxy X-Real-IP आणि X-Forwarded-For पाठवत आहे याची खात्री करा. तुमच्या नियंत्रणात नसलेली range कधीही सूचीबद्ध करू नका. Trusted network असल्यास कोणताही visitor तो header सेट करून प्रत्येक request साठी नवीन identity निवडू शकतो.

SearXNG limiter दर तासाला किती API requests अनुमत करते?

प्रत्येक IP address साठी दर तासाला चार. HTML व्यतिरिक्त इतर format मागणारी प्रत्येक request स्वतंत्र एक-तासांच्या window मध्ये मोजली जाते. ही मर्यादा searx/botdetection/ip_limit.py मध्ये सेट केलेली असते, limiter.toml मध्ये नाही. त्यामुळे ती config मधून वाढवता येत नाही. एखादा agent किंवा script एका task मध्ये ही मर्यादा ओलांडतो. Client चा address limiter.toml मधील pass_ip मध्ये जोडा किंवा internal network द्वारे instance शी संपर्क साधा. अशा network मध्ये limiter ला request दिसत नाही.

429 error न देता माझे search results रिकामे का येतात?

तुमचे users नव्हे, तर engines तुमचा server नाकारत आहेत. तुमच्या स्वतःच्या instance वर /stats/errors उघडा. त्यात fail झालेल्या प्रत्येक engine चे नाव आणि कारण दिलेले असते. CAPTCHA किंवा access-denied entry दिसत असल्यास त्या engine ने तुमच्या server चा IP address block केलेला आहे. too-many-requests उत्तर मिळाल्यानंतर SearXNG engine एक तासासाठी suspend करते. CAPTCHA मिळाल्यानंतर ते एक दिवसासाठी suspend करते. Upstream block कोणतीही local setting दूर करू शकत नाही. त्यामुळे तुमचा address block करणारे engines काढून टाका आणि उत्तर देणारे engines ठेवा.

Private instance वर limiter enable करावे का?

तुमच्याशिवाय कोणीही instance पर्यंत पोहोचत नसेल, तर limiter: false तसेच ठेवा. यामुळे Valkey dependency जोडली जाते आणि तुमचे स्वतःचे scripts block होतात. तुमच्याकडे नसलेल्या traffic पासून ते संरक्षण देते. Instance ला public address मिळताच ते public_instance: true सोबत enable करा. ही जोडी जाणूनबुजून अशी ठेवलेली आहे: public_instance: true enable असताना Valkey कार्यरत नसेल, तर process unprotected स्थितीत चालू राहण्याऐवजी status 1 ने exit होते.