Sửa lỗi CAPTCHA từ engine trong SearXNG
SearXNG trên VPS dễ nhận trang CAPTCHA hơn mạng gia đình. Phân biệt lỗi HTTP 429 với challenge từ engine và chọn cách sửa vẫn giữ hiệu lực sau khi restart.
Ý nghĩa của lỗi CAPTCHA trong SearXNG
Lỗi CAPTCHA trong SearXNG xuất phát từ các engine mà instance của bạn truy vấn. Server của bạn yêu cầu một engine trả kết quả, nhưng engine trả về một trang challenge thay vì kết quả. SearXNG ghi nhận lỗi đối với engine đó vì không có dữ liệu nào trong phản hồi để parse. Instance của bạn vẫn hoạt động bình thường. Một máy chủ mà bạn không kiểm soát đã quyết định rằng request của bạn không giống request do người dùng thực hiện.
Sự thật này quyết định mọi cách xử lý bên dưới. Quyết định được đưa ra trên phần cứng của chính engine đó, vì vậy không thiết lập nào trong settings.yml có thể ghi đè quyết định này. Bạn có thể thay đổi địa chỉ mà request sử dụng để đi ra ngoài, các engine được truy vấn, và cách instance phản ứng khi một engine bắt đầu từ chối request.
Hai lỗi trông giống nhau và cách phân biệt
Lỗi đầu tiên là instance của bạn trả HTTP 429 (quá nhiều request) cho chính browser của bạn. Đây là limiter của SearXNG, lớp phát hiện bot nằm trước search endpoint. Nó chạy trên máy chủ của bạn và bạn có thể tự cấu hình. limiter trả 429 cho chính người dùng của bạn là một vấn đề riêng với các thiết lập riêng, nên không có hướng dẫn nào dưới đây áp dụng cho vấn đề đó.
Lỗi thứ hai nằm ở upstream. Trang kết quả vẫn tải bình thường, nhưng một hoặc nhiều engine không xuất hiện trong kết quả hoặc có thông báo lỗi. Instance của bạn không từ chối request nào. Một engine đã từ chối server của bạn.
- Trang không tải được hoặc search endpoint trả 429: kiểm tra limiter.
- Trang tải được nhưng kết quả quá ít, hoặc một engine bị đánh dấu lỗi: kiểm tra upstream và tiếp tục đọc.
Cả hai lỗi có thể xảy ra trên cùng một instance và tác động lẫn nhau, vì limiter được cấu hình quá lỏng sẽ cho phép lưu lượng đi vào, làm tăng rate của các query gửi ra ngoài. Hãy chẩn đoán từng lỗi một.
Vì sao engine SearXNG trả về lỗi CAPTCHA trên VPS nhưng không lỗi trên laptop?
Vì địa chỉ gửi request khác nhau. Kết nối tại nhà của bạn dùng địa chỉ thuộc dải của ISP dành cho người dùng cá nhân, được chia sẻ theo thời gian với nhiều người dùng thông thường. VPS dùng địa chỉ thuộc dải của datacentre. Các dải này được công khai, nên bất kỳ ai cũng có thể tra cứu địa chỉ nào thuộc nhà cung cấp hosting. Engine muốn ngăn scraper thường bắt đầu bằng cách xem các request từ dải hosting là đáng ngờ, vì chỉ có rất ít request trong các dải này đến từ người dùng thật đang dùng trình duyệt.
Một số yếu tố khác cũng làm tăng mức độ đáng ngờ của địa chỉ. Instance của bạn gửi một request đến mỗi engine cho mỗi lần tìm kiếm của người dùng. Vì vậy, chỉ một số ít người dùng cũng có thể tạo ra rate từ một địa chỉ mà một cá nhân không thể tạo ra. Theo thiết kế, SearXNG không duy trì session với engine và không gửi cookie có thời hạn dài. Do đó, mọi request đều đến mà không có lịch sử trước đó. Địa chỉ này cũng có thể mang theo lịch sử mà bạn không tạo ra, vì nhà cung cấp tái sử dụng địa chỉ và tenant trước đó có thể đã dùng địa chỉ này để scraping trong nhiều tháng.
Engine không phải lúc nào cũng từ chối theo cách dễ nhận biết. Engine có thể trả về 403, 429, hoặc HTTP 200 kèm một trang challenge trong response body. Trường hợp cuối dễ gây nhầm lẫn, vì kiểm tra status code cho thấy engine vẫn hoạt động, trong khi SearXNG không tìm thấy kết quả nào trong response. Vì vậy, hãy đọc error report của chính instance thay vì dùng curl đến engine rồi chỉ xem status line.
Đọc thông tin instance báo cáo trước khi thay đổi bất cứ thứ gì
Mỗi cách khắc phục dưới đây đều bắt đầu bằng tên engine đang lỗi và lý do instance đã ghi nhận cho engine đó. SearXNG cung cấp cả hai thông tin này. Trang /stats liệt kê các engine cùng số lần lỗi và độ tin cậy. /stats/errors trả về thông tin chi tiết về lỗi dưới dạng JSON, dễ lưu lại và so sánh vào tuần sau hơn. Hãy mở các trang này bằng trình duyệt bạn thường dùng cho instance.
Log của container ghi lại các sự kiện tương tự ngay khi chúng xảy ra. Tên service ở đây là tên được dùng trong compose file đi kèm tài liệu của container. Nếu tên của bạn khác, hãy dùng tên đó.
docker compose logs -f coreChạy một lượt tìm kiếm bị lỗi trong khi đang theo dõi log. Bạn sẽ thấy một entry của engine bị lỗi xuất hiện khi lượt tìm kiếm chạy. Ghi lại tên engine và chuỗi lý do chính xác mà instance in ra. Không sao chép tên engine từ một bài blog, kể cả bài này. Danh sách engine gặp vấn đề với các địa chỉ datacenter thay đổi theo từng tháng. Engine bị lỗi trên instance của bạn có thể vẫn hoạt động bình thường trên instance của tác giả bài viết bạn đang đọc.
Nếu trang kết quả hoàn toàn không hiển thị lỗi nhưng có ít kết quả, hãy kiểm tra display_error_messages của engine đó. Giá trị mặc định là true. Instance đã tắt tùy chọn này sẽ ẩn chính thông báo bạn cần.
Cách SearXNG retry và tạm ngưng engine bị lỗi
SearXNG không liên tục gửi request đến một engine đã từ chối request. Engine bị lỗi sẽ bị tạm ngưng. Trong thời gian đó, SearXNG bỏ qua hoàn toàn engine này. Vì vậy, engine bị hỏng sẽ trở thành engine âm thầm biến mất khỏi kết quả.
Có 2 lớp kiểm soát việc này. Cả 2 đều nằm dưới search: trong settings.yml. Trước khi dán bất kỳ nội dung nào, hãy đối chiếu tên và giá trị của các key này với searx/settings.yml cho đúng version bạn đang chạy. Các key này đã thay đổi vị trí giữa các release. Ngoài ra, ví dụ trên trang tài liệu settings vẫn hiển thị thời gian tạm ngưng dài hơn thời gian mà file SearXNG thực sự load. Trong searx/settings.yml được release vào ngày 17 October 2026, giá trị mặc định là:
search:
ban_time_on_fail: 5
max_ban_time_on_fail: 120
suspended_times:
SearxEngineAccessDenied: 180
SearxEngineCaptcha: 3600
SearxEngineTooManyRequests: 180
cf_SearxEngineCaptcha: 1296000
cf_SearxEngineAccessDenied: 86400
recaptcha_SearxEngineCaptcha: 604800Lớp thứ nhất xử lý các lỗi thông thường như timeout. Thời gian ban đầu của lệnh ban là ban_time_on_fail giây và tăng sau mỗi lần lỗi liên tiếp, tối đa là max_ban_time_on_fail. Mặc định, giới hạn là 2 phút. Vì vậy, engine chập chờn sẽ tự hoạt động lại trong vòng vài phút sau khi sự cố biến mất.
Lớp thứ hai xử lý các lỗi được đề cập trong hướng dẫn này. Khi SearXNG nhận diện response là challenge hoặc refusal thay vì lỗi chung, nó áp dụng entry tương ứng trong suspended_times. Phần lớn các giá trị này lớn hơn nhiều. 180 giây là 3 phút, áp dụng cho refusal thông thường hoặc mã 429. 3600 là 1 giờ, áp dụng cho CAPTCHA chung. 86400 là cả 1 ngày. 604800 là 1 tuần. 1296000 là 15 ngày. Các key có tiền tố cf_ được áp dụng khi challenge được nhận diện là challenge của Cloudflare. Các key có tiền tố recaptcha_ được áp dụng khi challenge được nhận diện là reCAPTCHA.
Điều này giải thích triệu chứng gây mất nhiều thời gian nhất. Bạn tìm ra nguyên nhân và khắc phục nó, nhưng engine vẫn không trả về kết quả trong 1 giờ, hoặc trong nhiều ngày sau một challenge của Cloudflare. Engine vẫn đang bị tạm ngưng. Trạng thái tạm ngưng được giữ trong process đang chạy. Vì vậy, restart container sẽ xóa trạng thái này và search tiếp theo sẽ thử lại engine. Ở đây, chỉ cần restart là đủ. Tuy nhiên, bạn nên biết khi nào restart là đủ và khi nào cần tạo lại container trước khi rebuild image không cần thiết. Nếu engine lại lỗi ngay sau khi restart, bản sửa của bạn chưa có tác dụng.
Có một setting riêng cho từng engine cần lưu ý. retry_on_http_error retry request khi engine trả về các status code mà bạn liệt kê. Nếu engine đang block bạn, các lần retry sẽ gửi thêm network traffic đến hệ thống đã xác định server của bạn là bot. Hãy để nguyên setting này, trừ khi bạn đang xử lý một engine thực sự hoạt động không ổn định.
Tài liệu upstream về SSH tunnel và những gì nó không khắc phục được
Được kiểm tra vào ngày 17 October 2026, tài liệu quản trị SearXNG giải quyết vấn đề này bằng một tunnel thủ công. Bạn mở một SOCKS proxy thông qua server, cấu hình trình duyệt trên desktop sử dụng proxy đó, rồi tự trả lời challenge trong khi engine nhìn thấy địa chỉ của server.
ssh -q -N -D 8080 user@example.org-D 8080 mở một SOCKS server cục bộ trên port 8080 và chuyển tiếp lưu lượng qua kết nối SSH. -N không chạy command từ xa, còn -q giữ cho command im lặng. Vì vậy, tunnel hoạt động bình thường sẽ không in gì và không trả về prompt. Kiểm tra tunnel từ terminal thứ hai:
curl -x socks://127.0.0.1:8080 http://ipecho.net/plain
curl http://ipecho.net/plainCommand đầu tiên phải in ra địa chỉ của server, còn command thứ hai phải in ra địa chỉ của desktop. Nếu hai kết quả giống nhau, request không đi qua tunnel. Sau đó, đặt network settings của trình duyệt sử dụng SOCKS5 proxy tại 127.0.0.1, port 8080. Mở cùng một address checker trong trình duyệt để xác nhận nó báo cáo địa chỉ của server, rồi truy cập engine đang yêu cầu bạn trả lời challenge. Trả lời challenge tại đó.
Bây giờ là phần cần nói rõ. Phương pháp này có 4 giới hạn. Cookie do engine cấp sẽ nằm trong trình duyệt trên desktop. SearXNG không có quyền truy cập cookie của trình duyệt, nên thứ duy nhất có thể giúp instance của bạn là thông tin engine ghi nhận đối với chính địa chỉ đó. Thông tin này sẽ hết hạn theo lịch do engine quyết định và không công bố. Không có phần nào trong quy trình được tự động hóa, nên lần sau bạn vẫn phải quay lại thao tác thủ công. Với một instance có người khác sử dụng, query rate đã kích hoạt challenge vẫn tiếp tục chạy, nên challenge sẽ xuất hiện lại.
Dùng cách này để đưa một instance hoạt động trong hôm nay. Không xây dựng một instance dựa trên cách này.
Cách khắc phục lâu dài: tắt hoặc giảm trọng số các engine gây lỗi
Cách bền vững và ít tốn kém nhất là ngừng truy vấn một engine không thể phục vụ server của bạn. settings.yml bắt đầu bằng use_default_settings: true trong container image. Vì vậy, một mục trong engines: có name tương ứng sẽ chỉ ghi đè những key bạn khai báo và giữ nguyên các phần còn lại của định nghĩa mặc định.
use_default_settings: true
engines:
- name: <engine name from your stats page>
disabled: true
- name: <another engine name>
weight: 0.3disabled: true tắt engine theo mặc định nhưng vẫn giữ engine trên trang tùy chọn. Người dùng cần engine này vẫn có thể tự bật lại cho các tìm kiếm của họ. inactive: true xóa engine hoàn toàn khỏi phần cài đặt người dùng. Đây là lựa chọn phù hợp với engine sẽ không bao giờ hoạt động từ địa chỉ của bạn. weight có tác dụng khác: tham số này điều chỉnh mức độ kết quả của engine được tính đến khi SearXNG gộp và xếp hạng kết quả. Vì vậy, trọng số nhỏ hơn 1 giúp giữ lại một engine hoạt động không ổn định mà không để nó chiếm các vị trí đầu tiên.
Sau khi chỉnh sửa, hãy restart container, thực hiện vài lượt tìm kiếm rồi kiểm tra lại /stats. Một trang thống kê sạch với sáu engine hoạt động hữu ích hơn một trang đầy lỗi với hai mươi engine.
Cách khắc phục bền vững: gửi request đi qua proxy
SearXNG có thể gửi các request đến engine qua proxy. Nhờ đó, địa chỉ mà engine nhìn thấy sẽ thay đổi. Cấu hình proxy dùng chung tại outgoing:, hoặc cấu hình riêng cho từng engine nếu chỉ một engine gặp vấn đề.
outgoing:
request_timeout: 3.0
extra_proxy_timeout: 10
proxies:
all://:
- socks5h://user:password@proxy:1080engines:
- name: <engine name>
proxies:
http: socks5h://user:password@proxy:1080
https: socks5h://user:password@proxy:1080Ưu tiên socks5h:// thay vì socks5:// nếu bạn muốn proxy phân giải hostname. h khiến tên được gửi đến proxy thay vì được tra cứu trên server của bạn. Đồng thời, hãy tăng ngân sách timeout. request_timeout mặc định là 3.0 giây. Proxy thêm một round trip vào mỗi request, nên các engine trước đây trả lời kịp thời có thể bắt đầu fail do timeout. extra_proxy_timeout được thiết kế cho trường hợp này và cộng thêm số giây khi đang dùng proxy. Hãy ghi giá trị này dưới dạng số nguyên, chẳng hạn 10. Không giống request_timeout, chấp nhận số thập phân, extra_proxy_timeout là một số nguyên trong schema settings. Vì vậy, giá trị như 10.0 sẽ bị từ chối dưới dạng settings.yml không hợp lệ, dù ví dụ được comment trên trang tài liệu về outgoing settings lại ghi theo cách đó.
Proxy có những chi phí sau:
- Nhà vận hành proxy biết instance của bạn truy vấn những engine nào và vào thời điểm nào. TLS (transport layer security) giữ search terms không xuất hiện trong log của họ vì query nằm bên trong request đã được mã hóa. Tuy nhiên, họ vẫn đọc được đặc điểm và thời điểm của network traffic.
- Địa chỉ exit dùng chung sẽ được chia sẻ với những người khác cũng trả phí sử dụng. Nếu họ scrape, bạn sẽ thừa hưởng reputation của họ, đôi khi nhanh hơn cả block mà bạn đang cố tránh.
- Các pool residential proxy giá rẻ thường được xây dựng từ những thiết bị của người dùng mà chủ thiết bị không hề biết hoặc không đồng ý cho chuyển tiếp traffic. Hãy biết rõ thứ bạn đang mua.
using_tor_proxy: trueđịnh tuyến qua Tor, nhưng địa chỉ của exit node được công khai đầy đủ. Engine vốn chặn các dải địa chỉ datacentre thường cũng chặn exit node nghiêm ngặt không kém.- Search giờ đây phụ thuộc vào một service bên ngoài server của bạn. Service đó có thể tự gặp sự cố và làm kết quả của bạn biến mất theo.
Proxy chỉ chuyển block sang nơi khác, không loại bỏ block. Privacy của instance giờ cũng phụ thuộc vào một bên thứ ba. Nếu privacy là lý do chính khiến bạn self-host, hãy cân nhắc điều đó với những gì instance self-host thực sự che giấu và những gì nó không che giấu trước khi đăng ký bất kỳ dịch vụ nào.
Cách khắc phục bền vững: chủ động chạy bộ engine nhỏ hơn
Lựa chọn mà nhiều người bỏ qua nhất là chấp nhận ít engine hơn. Giá trị của SearXNG nằm ở việc gộp kết quả, và một tập hợp 6 engine luôn trả lời hiệu quả hơn 20 engine trong đó một nửa bị tạm ngưng hàng giờ hoặc hàng ngày. Theo dõi /stats trong 1 tuần và giữ lại những engine hoạt động ổn định từ địa chỉ của bạn.
Các engine yêu cầu xác thực bằng API key hoạt động khác, vì engine biết bạn là ai và áp dụng quota thay vì phải đoán bạn có phải người dùng hay không. Đổi lại, bạn cần một account, một key được lưu trong file settings và thường phải trả phí. Với 1 hoặc 2 engine quan trọng với bạn, đây thường là cách ít rắc rối nhất.
Hãy quyết định dựa trên các tool khác mà bạn đang dùng. Một engine bị tạm ngưng sẽ vô hình đối với mọi thứ đọc kết quả qua API, vì JSON API mà Open WebUI và các tool tương tự truy vấn chỉ trả về ít kết quả hơn thay vì trả về lỗi mà tool của bạn có thể phát hiện. Nếu có automation phụ thuộc vào instance của bạn, hãy định kỳ kiểm tra /stats/errors thay vì chờ ai đó phàn nàn rằng chất lượng câu trả lời đã giảm.
Có đáng để cố xử lý việc này không?
Hãy trả lời bằng cách đếm số người dùng. Một instance chỉ dành cho một người sẽ gửi một số ít truy vấn mỗi ngày từ một địa chỉ, với tần suất mà nhiều search engine không bao giờ yêu cầu xác minh. Khi một engine yêu cầu xác minh, cách xử lý rất đơn giản: bỏ engine đó và bạn hầu như không nhận thấy nó đã biến mất. Đây là trải nghiệm thông thường khi chạy SearXNG cho nhu cầu cá nhân trên một VPS nhỏ, và bạn không cần tunnel hay proxy.
Một instance công khai hoặc dùng chung là một máy khác chạy cùng phần mềm. Tần suất truy vấn là yếu tố kích hoạt, và nó tăng theo từng người dùng bạn thêm vào, nên các yêu cầu xác minh sẽ xuất hiện nhanh hơn khả năng xử lý của mọi cấu hình. Hãy bắt đầu với một bộ engine nhỏ hơn, đồng thời nhớ rằng mọi proxy bạn thêm vào lúc này sẽ chuyển các truy vấn của người khác qua account của bạn.
Các client tự động nằm ở giữa nhưng có xu hướng gần với trường hợp khó hơn. Một agent thực hiện nhiều truy vấn để trả lời một câu hỏi sẽ tạo ra các đợt truy vấn mà con người không tạo ra, vì vậy một instance được dùng cho coding agent và công cụ nghiên cứu sẽ gặp yêu cầu xác minh sớm hơn instance được sử dụng thủ công. Nếu đây là nhu cầu của bạn, hãy chọn bộ engine dựa trên độ tin cậy thay vì độ rộng, và để agent làm việc với những kết quả mà nó thực sự lấy được.
Quy tắc chung là: hãy cố xử lý một engine khi đó là lý do bạn self-host, và bỏ nó khi không phải như vậy.
FAQ
Tại sao engine SearXNG vẫn không trả về kết quả sau khi tôi đã sửa lỗi?
Vì engine vẫn đang bị tạm ngưng. Khi SearXNG phát hiện challenge hoặc bị engine từ chối, nó sẽ ngừng gửi query đến engine đó trong khoảng thời gian được đặt ở search.suspended_times. Giá trị mặc định đi kèm có thể từ ba phút đến mười lăm ngày, tùy loại từ chối. Trạng thái tạm ngưng được giữ trong process đang chạy, vì vậy restart container sẽ xóa trạng thái này và lần search tiếp theo sẽ thử lại engine. Nếu engine tiếp tục fail ngay sau khi restart, bản sửa của bạn chưa có tác dụng.
Lỗi CAPTCHA của engine có giống lỗi 429 mà instance của tôi trả về không?
Không. Hai lỗi này phát sinh theo hai hướng ngược nhau. Lỗi 429 từ instance của bạn đến browser là do limiter của SearXNG nhận định request có vẻ được tự động hóa. Bạn có thể tự cấu hình limiter này. Lỗi CAPTCHA hoặc block là do engine upstream từ chối server của bạn, theo quyết định trên hạ tầng mà bạn không kiểm soát. Nếu trang kết quả vẫn load nhưng chỉ thiếu một số engine, bạn đang gặp trường hợp thứ hai.
VPN hoặc proxy trên server có xử lý được CAPTCHA của engine không?
Đôi khi có, nhưng sẽ phát sinh chi phí. Định tuyến request đi qua outgoing.proxies sẽ thay đổi địa chỉ mà engine nhìn thấy. Cách này có thể gỡ block gắn với dải địa chỉ của datacenter. Nhà vận hành proxy sẽ biết bạn query engine nào và vào thời điểm nào. Địa chỉ exit dùng chung cũng mang theo reputation của các khách hàng khác. Latency tăng thêm có thể gây timeout nếu bạn không tăng request_timeout và extra_proxy_timeout. Tor có thể được dùng thông qua using_tor_proxy, nhưng các địa chỉ exit của Tor được công khai và thường xuyên bị challenge.
Tôi có thể cấu hình SearXNG tự động giải CAPTCHA không?
Không có setting cho việc này. Phương pháp được project hướng dẫn là xử lý thủ công: dùng SSH SOCKS tunnel, browser của bạn và tự thực hiện challenge. Bất kỳ giải pháp nào bạn xây dựng để tự động trả lời challenge đều đi ngược chính sách của engine và sẽ âm thầm hỏng mỗi khi challenge thay đổi. Khi đó bạn phải duy trì một scraper thay vì vận hành một search instance. Cách giải quyết bền vững là xóa các engine đang block địa chỉ của bạn.