SSD Nodes Learn 🎉 VPS mulai $5.50/bln
Panduan Matt ConnorOleh Matt Connor

Cara Memperbaiki Error 429 dan Rate Limit SearXNG

Error 429 SearXNG punya dua penyebab: limiter lokal atau mesin pencari yang memblokir IP server. Baca log untuk menentukan perbaikan yang tepat.

Mengapa SearXNG mengembalikan error 429

Instance SearXNG yang di-hosting sendiri mengembalikan error 429 karena dua alasan yang tidak berkaitan, dan rate limit yang perlu Anda perbaiki biasanya bukan yang Anda duga. Alasan pertama bersifat lokal: limiter SearXNG sendiri menganggap sebuah request berasal dari bot, lalu menjawab Too Many Requests dengan status 429. Alasan kedua berasal dari upstream: mesin pencari menolak alamat IP server Anda. Bagi pengguna, kondisi ini muncul sebagai halaman hasil dengan beberapa bagian yang hilang, bukan sebagai error 429.

Kedua kasus tersebut memerlukan solusi yang berbeda. Limiter berada di sisi Anda, sehingga dapat diubah. Pemblokiran upstream terjadi di sisi Google, sehingga tidak ada pengaturan dalam settings.yml yang dapat mengatasinya. Log menunjukkan kasus yang terjadi dalam waktu sekitar satu menit, jadi mulailah dari sana.

Panduan ini mengasumsikan instalasi container yang dijelaskan dalam instance SearXNG yang di-hosting sendiri pada VPS Anda. Semua nama pengaturan di bawah ini berasal dari dokumentasi dan source upstream terbaru, yang diperiksa pada Agustus 2026.

Baca log sebelum mengubah pengaturan

Reproduksi masalah dengan jendela log yang terbuka.

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

Pesan limiter berasal dari logger bernama searx.limiter dan mencantumkan alamat IP. Hit blocklist ditulis sebagai BLOCK 203.0.113.10: matched BLOCKLIST, sedangkan hit allowlist ditulis sebagai PASS 203.0.113.10: matched PASSLIST. Jika limiter tidak dapat menjangkau penyimpanan penghitungnya, log akan menulis The limiter requires Valkey, please consult the documentation. Artinya, tidak ada apa pun yang sedang dihitung.

Setiap pemeriksaan bot dicatat pada level debug, sehingga secara default Anda tidak akan melihatnya. Aktifkan debug untuk satu pengujian di settings.yml:

general:
  debug: true

Log kemudian menambahkan baris berbentuk NOT OK (http_accept_language) di dekat jaringan klien dan mencantumkan pemeriksaan yang gagal. Nonaktifkan kembali setelah itu, karena upstream menyarankan agar instance yang sudah digunakan tidak dijalankan dengan debug aktif.

Kegagalan engine terlihat sangat berbeda. Kegagalan tersebut mencantumkan engine, bukan IP, dan yang paling umum adalah timeout:

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

Tersedia halaman untuk hal ini. Jika enable_metrics dibiarkan pada nilai default true, instance Anda mencatat error engine pada /stats/errors, dan /preferences mencantumkan engine yang saat ini merespons. Jika /stats/errors penuh dan log tidak berisi baris searx.limiter, limiter bukan penyebab masalah Anda.

Tetapkan versi sebelum melakukan debug

Konfigurasi container upstream terdiri atas dua file.

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

File compose mengambil docker.io/searxng/searxng:${SEARXNG_VERSION:-latest}. Variabel yang tidak ditetapkan berarti latest, sedangkan latest berarti instance berubah pada docker compose pull berikutnya. Akibatnya, pengaturan yang berfungsi minggu lalu dapat berhenti cocok dengan kode yang membacanya. Tag SearXNG memuat tanggal dan commit. Tag contoh dalam upstream .env.example per Agustus 2026 adalah 2026.3.25-541c6c3cb, jadi tetapkan nilai yang sebenarnya dalam .env:

SEARXNG_VERSION=2026.3.25-541c6c3cb

Periksa tag yang dipublikasikan dan tetapkan release yang benar-benar telah Anda uji. Setelah itu, lakukan debug terhadap target yang tetap. File .env yang sama menyimpan secret key Anda. Baca cara kerja file env dan secret di Docker Compose sebelum melakukan commit terhadap direktori tersebut di mana pun.

Limiter memerlukan Valkey, atau tidak akan berjalan

Limiter menghitung permintaan dari setiap klien. Hitungan tersebut harus dibagikan ke seluruh proses worker. Penyimpanan yang digunakan adalah Valkey, yaitu fork Redis yang masih dipelihara. Panduan SearXNG yang lebih lama menyebut pengaturan ini sebagai redis:. Rilis saat ini membaca valkey:. Karena itu, salin nama key dari dokumentasi terbaru, bukan dari tulisan lama.

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

File compose upstream sudah menjalankan service searxng-valkey menggunakan image docker.io/valkey/valkey:9-alpine. Karena itu, nama host tersebut dapat di-resolve di dalam jaringan compose. Nilai yang sama dapat ditetapkan dengan variabel lingkungan SEARXNG_VALKEY_URL. URL Unix socket (unix:///path/to/socket.sock?db=0) juga berfungsi jika SearXNG dan Valkey berjalan pada host yang sama.

Dampak ketika penyimpanan tidak tersedia bergantung pada satu key lainnya. Dengan public_instance: false, limiter mencatat error Valkey lalu berhenti, sehingga instance tetap melayani permintaan tanpa rate limiting sama sekali. Dengan public_instance: true, proses memanggil sys.exit(1) sebagai gantinya, karena instance terbuka dengan perlindungan bot yang rusak akan mengumpulkan CAPTCHA (completely automated public turing test to tell computers and humans apart) dari setiap engine dalam satu hari. Container yang terus restart dalam loop segera setelah Anda menetapkan public_instance: true mengalami kondisi ini. Baris terakhir sebelum setiap proses keluar menyebutkan Valkey.

Hal yang sebenarnya dihitung limiter

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 normal dapat mengirim 15 request dalam burst window 20 detik dan 150 request dalam window 10 menit. Setelah sebuah request ditandai sebagai mencurigakan, batas untuk client yang sama turun menjadi 2 per burst window. Baris terakhir merupakan aturan paling ketat: setelah 3 request yang ditandai dalam window 30 hari, address tersebut dialihkan ke halaman awal, bukan ke halaman pencarian, dan log mencatat BLOCK: too many request from ... in SUSPICIOUS_IP_WINDOW (redirect to /).

Angka-angka ini merupakan konstanta dalam searx/botdetection/ip_limit.py. Angka tersebut bukan pengaturan, dan limiter.toml tidak mengeksposnya. Jadi, untuk mengubahnya, Anda harus mengedit source. Yang dikendalikan oleh /etc/searxng/limiter.toml adalah prefix address yang digunakan untuk mengelompokkan client, daftar trusted proxy, pemeriksaan link token opsional, serta pass list dan block list.

Sebuah request ditandai sebagai mencurigakan berdasarkan pemeriksaan header. Setiap pemeriksaan memiliki nama yang akan terlihat dalam debug log:

  • http_accept: header Accept tidak memuat text/html.
  • http_accept_encoding: header Accept-Encoding tidak mencantumkan gzip maupun deflate.
  • http_accept_language: tidak ada header Accept-Language.
  • http_connection: header Connection ditetapkan ke close.
  • http_user_agent: User-Agent tidak ada atau cocok dengan pola bot yang telah dikenal.
  • http_sec_fetch: header Sec-Fetch-Mode atau Sec-Fetch-Dest tidak berisi nilai yang dikirim browser.

Browser mengirim semua header tersebut. Pemanggilan curl biasa hampir tidak mengirim satupun, sehingga request pengujian yang ditulis manual langsung ditandai pada percobaan pertama, sementara pencarian yang sama berhasil dari tab browser. Karena itu, hasil “berfungsi di browser saya, tetapi script saya mendapat 429” merupakan hasil yang wajar, bukan sesuatu yang misterius.

Limiter di balik reverse proxy memblokir semua pengguna sekaligus

Ini adalah cara paling umum untuk merusak instance yang sebelumnya berfungsi. SearXNG mengambil alamat klien dari IP tidak tepercaya pertama dalam X-Forwarded-For, kemudian menggunakan X-Real-IP sebagai cadangan, dan kembali menggunakan alamat yang membuka koneksi. Apakah header tersebut dipercaya ditentukan oleh trusted_proxies dalam limiter.toml.

Jika alamat proxy Anda tidak tercantum dalam daftar tersebut, header akan diabaikan dan setiap pengunjung akan terlihat menggunakan alamat proxy. Akibatnya, semua pengunjung berbagi satu penghitung. Seluruh situs akan diblokir setelah jumlah total permintaan melampaui 150 dalam 10 menit. Satu pengguna yang memuat ulang halaman hasil beberapa kali dapat membuat semua pengguna lain ikut terblokir.

Terlalu banyak memberikan kepercayaan lebih berbahaya. Jika rentang publik tercantum, pengunjung mana pun dapat mengirim header X-Forwarded-For mereka sendiri dan memilih identitas baru pada setiap permintaan. Hal ini menonaktifkan limiter bagi siapa pun yang mengetahui cara mencobanya. Cantumkan hanya alamat asal koneksi proxy Anda. Dalam Docker, alamat tersebut biasanya berada pada jaringan bridge di dalam 172.16.0.0/12, dan baris itu secara default dikomentari.

[botdetection]
ipv4_prefix = 32
ipv6_prefix = 48

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

Proxy juga harus mengirimkan header tersebut. Nginx tidak menambahkan header apa pun secara otomatis:

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 dan Traefik menetapkan forwarded header untuk Anda. Dengan keduanya, Anda hanya perlu menyelesaikan bagian trusted_proxies. Pertimbangan komprominya dibahas dalam memilih reverse proxy untuk service self-hosted. Untuk memverifikasi salah satu konfigurasi, aktifkan debug, lakukan satu kali pencarian dari ponsel menggunakan data seluler, lalu pastikan jaringan pada baris log menunjukkan alamat ponsel Anda, bukan alamat proxy.

Agen Anda mendapatkan empat permintaan API per jam

Output JSON dinonaktifkan secara default, jadi agen harus menambahkannya:

search:
  formats:
    - html
    - json

Sekarang baca kembali baris tabel. Setiap permintaan yang meminta format selain HTML dihitung dalam jendela tersendiri: 4 permintaan per 1 hour, per alamat. Agen riset dapat menghabiskan batas itu dalam satu tugas, dan setiap pemanggilan setelahnya mengembalikan 429. Menaikkan batas bukan pilihan, karena jumlah tersebut ditetapkan di dalam source code.

Solusi yang tepat adalah memberi tahu limiter bahwa klien ini bukan klien asing. Tambahkan alamatnya ke pass list di limiter.toml:

[botdetection.ip_lists]
block_ip = []

pass_ip = [
  '10.8.0.0/24',
]

pass_searxng_org = true

pass_ip memiliki prioritas atas semua metode lain, sehingga klien yang masuk allowlist juga melewati pemeriksaan header dan pemanggilan curl tanpa argumen dapat berjalan. Usahakan rentangnya sekecil mungkin, dan pilih subnet VPN atau jaringan container, bukan jaringan yang dapat dirutekan dari luar. Solusi tepat lainnya adalah sepenuhnya mengeluarkan agen dari jalur publik: arahkan agen ke alamat container pada jaringan internal, tempat proxy dan limiter-nya tidak pernah melihat trafik tersebut. Konfigurasi ini dibahas dalam memberi agen AI kemampuan pencarian SearXNG.

Hindari mengarahkan agen ke instance publik yang dijalankan orang lain. Cara ini paling cepat menyebabkan alamat IP sukarelawan diblokir oleh engine upstream, dan itulah alasan format JSON dinonaktifkan secara default sejak awal.

Ketika engine justru memblokir Anda

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"
  }
]

Ketika sebuah engine merespons dengan kode 429 miliknya sendiri atau halaman CAPTCHA, SearXNG memunculkan exception bernama dan berhenti meminta data dari engine tersebut untuk sementara. Respons too-many-requests menangguhkan engine selama 3600 detik. CAPTCHA biasa atau respons access-denied menangguhkannya selama 1 day. CAPTCHA yang disajikan melalui Cloudflare menangguhkannya selama 15 days, durasi default terlama dalam daftar, karena respons tersebut berarti pemblokiran terjadi di edge dan percobaan ulang tidak akan membantu.

Kegagalan biasa menggunakan pengaturan yang berbeda. Timeout atau parse error menangguhkan engine selama waktu singkat yang diturunkan dari search.ban_time_on_fail, yang secara default bernilai 5 detik dan dibatasi oleh search.max_ban_time_on_fail hingga 120 detik. Jadi, engine yang lambat pulih sendiri dalam beberapa menit, sedangkan engine yang diblokir tidak tersedia selama berjam-jam. Perbedaan ini menjelaskan gejala yang sering dianggap acak: hasil pencarian awalnya normal, lalu hasil dari satu engine menghilang hingga sore hari.

Perbaiki timeout sebelum menyalahkan pihak lain. Nilai default request_timeout adalah 2.0 detik. Nilai ini cukup ketat untuk VPS kecil yang berada jauh dari edge server terdekat milik engine.

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

request_timeout adalah default untuk setiap engine, max_request_timeout adalah batas atasnya, dan satu engine dapat memiliki timeout sendiri. Menaikkan nilai ini mengorbankan latensi halaman untuk mengurangi kegagalan. Naikkan dalam interval setengah detik dan pantau /stats/errors, bukan langsung menaikkannya menjadi 10.

Untuk engine yang benar-benar memblokir alamat Anda, hapus engine tersebut. Setiap pencarian menunggu engine yang paling lambat. Karena itu, mempertahankan engine yang terus-menerus ditangguhkan hanya menambah latensi dan tidak menghasilkan apa pun.

use_default_settings:
  engines:
    remove:
      - google

Terapkan perubahan dengan docker compose restart searxng-core, lalu jalankan beberapa pencarian dan muat ulang /stats/errors. Jika halaman kosong setelah 5 menit penggunaan nyata, berarti perubahan tersebut berhasil.

Alamat IP pusat data akan dianggap sebagai bot

Alamat VPS Anda berada dalam rentang hosting, dan mesin pencari besar menilai rentang tersebut sebagai sumber otomatisasi. Beberapa di antaranya menampilkan CAPTCHA untuk setiap permintaan dari alamat seperti itu, terlepas dari seberapa wajar header atau seberapa lambat lajunya. Tidak ada pengaturan dalam settings.yml yang dapat mengubah penilaian tersebut.

Yang dapat Anda ubah adalah mesin pencari yang digunakan dan apakah instance Anda terdaftar secara publik. Instance privat yang digunakan oleh satu rumah tangga biasanya jarang memicu pemblokiran. Instance publik pada IP hosting akan mengalami penangguhan pada mesin pencari yang paling ketat. Kondisi tersebut merupakan perilaku normal software, bukan kesalahan dalam konfigurasi Anda. SearXNG dapat merutekan permintaan ke mesin pencari melalui proxy dengan outgoing.proxies atau outgoing.using_tor_proxy, sehingga trafik berpindah ke alamat lain. Exit node dan kumpulan proxy murah dinilai lebih buruk daripada rentang hosting, jadi perpindahan tersebut dapat membuat hasil pencarian menjadi lebih buruk.

Pantau instance agar masalah segera diketahui

SearXNG tetap memberikan respons pada portnya meskipun semua engine ditangguhkan. Karena itu, pemeriksaan uptime yang hanya memantau kode status akan tetap berstatus baik meskipun instance tidak mengembalikan apa pun. Periksa juga kontennya: lakukan pencarian nyata dan cocokkan kata yang Anda harapkan dalam body respons. pemantauan kata kunci Uptime Kuma melakukan hal tersebut tanpa tool tambahan. Pantau /stats/errors setelah setiap pembaruan versi karena engine dapat mengubah HTML-nya dan parser dapat rusak tanpa ada kaitannya dengan rate limit.

FAQ

Mengapa SearXNG mengembalikan 429 kepada setiap pengunjung setelah saya menempatkannya di balik reverse proxy?

Karena limiter menghitung proxy sebagai client. SearXNG hanya membaca X-Forwarded-For jika alamat yang terhubung tercantum dalam trusted_proxies di /etc/searxng/limiter.toml. Jika tidak tercantum, semua pengunjung berbagi satu counter dan bersama-sama melewati batas 150 requests per 10 minutes. Tambahkan alamat tempat proxy terhubung. Dalam Docker, alamat ini biasanya berupa bridge range 172.16.0.0/12. Pastikan proxy mengirim X-Real-IP dan X-Forwarded-For. Jangan pernah mencantumkan range yang tidak Anda kendalikan. Jaringan tepercaya memungkinkan pengunjung mana pun mengatur header tersebut dan memilih identitas baru untuk setiap request.

Berapa banyak API requests per hour yang diizinkan oleh limiter SearXNG?

Empat per alamat IP per hour. Request yang meminta format selain HTML dihitung dalam jendela one hour yang terpisah. Batas tersebut diatur dalam searx/botdetection/ip_limit.py, bukan dalam limiter.toml, sehingga tidak dapat dinaikkan melalui config. Agent atau script dapat melewati batas tersebut dalam satu task. Tambahkan alamat client ke pass_ip dalam limiter.toml, atau akses instance melalui jaringan internal agar limiter tidak pernah melihat request tersebut.

Mengapa hasil pencarian saya kosong tanpa error 429?

Engine menolak server Anda, bukan user Anda. Buka /stats/errors pada instance Anda sendiri. File tersebut mencantumkan setiap engine yang gagal dan alasannya. Entri CAPTCHA atau access-denied berarti engine tersebut memblokir alamat IP server Anda. SearXNG kemudian menangguhkan engine tersebut selama satu jam setelah menerima jawaban too-many-requests dan selama satu hari setelah menerima CAPTCHA. Tidak ada pengaturan lokal yang dapat menghapus pemblokiran dari upstream. Hapus engine yang memblokir alamat Anda dan pertahankan engine yang memberikan jawaban.

Apakah saya harus mengaktifkan limiter pada instance privat?

Jika tidak ada yang mengakses instance selain Anda, biarkan limiter: false. Limiter menambahkan dependensi Valkey dan memblokir script Anda sendiri, padahal limiter melindungi dari traffic yang tidak Anda miliki. Aktifkan segera setelah instance memiliki alamat publik, bersama dengan public_instance: true. Pasangan tersebut memang dirancang demikian. Dengan public_instance: true dan Valkey yang tidak berfungsi, proses keluar dengan status 1, bukan berjalan tanpa perlindungan.