SearXNG 검색 엔진 CAPTCHA 오류 해결 방법
SearXNG 인스턴스에서 발생하는 업스트림 CAPTCHA 오류의 원인을 분석합니다. VPS IP 차단 문제를 해결하고 재시작 후에도 설정이 유지되는 실질적인 대응책을 제시합니다.
SearXNG CAPTCHA 오류의 의미
SearXNG CAPTCHA 오류는 인스턴스가 쿼리를 보내는 검색 엔진에서 발생합니다. 서버가 엔진에 검색 결과를 요청했으나, 엔진이 결과 대신 챌린지 페이지를 반환했습니다. SearXNG는 응답에서 파싱할 내용을 찾지 못해 해당 엔진에 오류를 기록한 것입니다. 인스턴스 자체는 정상입니다. 귀하가 제어할 수 없는 외부 시스템이 귀하의 요청을 사람이 보낸 것으로 판단하지 않은 것입니다.
이 사실이 아래의 모든 해결책을 결정합니다. 판단은 엔진 측 하드웨어에서 이루어지므로 귀하의 settings.yml 설정으로는 이를 무효화할 수 없습니다. 변경 가능한 것은 요청이 나가는 IP 주소, 쿼리를 보낼 엔진의 선택, 그리고 엔진이 거부를 시작했을 때 인스턴스가 동작하는 방식뿐입니다.
겉보기엔 같아 보이는 두 가지 오류와 구분 방법
첫 번째 오류는 사용자의 인스턴스가 사용자의 브라우저에 HTTP 429(너무 많은 요청)를 응답하는 경우입니다. 이는 검색 엔드포인트 앞단에 위치한 봇 탐지 계층인 SearXNG 리미터(limiter)입니다. 이 리미터는 사용자의 서버에서 실행되며 사용자가 직접 설정해야 합니다. 사용자에게 429를 반환하는 리미터는 별도의 설정이 필요한 독립적인 문제이므로, 아래의 조언은 해당 문제에 적용되지 않습니다.
두 번째 오류는 업스트림(upstream) 문제입니다. 결과 페이지는 정상적으로 로드되지만, 하나 이상의 엔진에서 결과가 누락되거나 오류 알림이 표시됩니다. 인스턴스 측에서는 아무것도 거부하지 않았으나, 검색 엔진이 사용자의 서버를 거부한 상황입니다.
- 페이지가 로드되지 않거나 검색 엔드포인트가 429를 응답하는 경우: 리미터를 확인하십시오.
- 페이지는 로드되지만 결과가 부족하거나 엔진에 오류가 표시되는 경우: 업스트림을 확인하고 아래 내용을 계속 읽으십시오.
두 오류는 동일한 인스턴스에서 동시에 발생할 수 있으며 서로 영향을 줍니다. 리미터 설정이 너무 느슨하면 과도한 트래픽이 유입되어 외부로 나가는 쿼리 비율이 높아지기 때문입니다. 각각 따로 진단하십시오.
왜 SearXNG 엔진은 노트북에서는 괜찮은데 VPS에서는 CAPTCHA 오류를 반환합니까?
요청이 발생하는 IP 주소 때문입니다. 가정용 인터넷 연결은 일반적인 ISP(인터넷 서비스 제공업체) 대역의 주소를 사용하며, 이 주소는 시간이 지남에 따라 많은 일반 사용자와 공유됩니다. 반면 VPS는 데이터센터 대역의 주소를 사용하는데, 이 대역은 공개되어 있어 누구나 해당 주소가 호스팅 제공업체에 속해 있는지 확인할 수 있습니다. 스크래퍼를 차단하려는 엔진은 호스팅 대역에서 들어오는 요청을 의심스러운 것으로 간주합니다. 해당 대역에서 브라우저를 사용하는 일반 사용자의 요청은 거의 발생하지 않기 때문입니다.
주소 외에도 몇 가지 요인이 더 있습니다. 귀하의 인스턴스는 사용자 검색마다 엔진당 하나의 요청을 보내므로, 소수의 사용자만 있어도 개인이 발생시키는 수준을 훨씬 넘어서는 요청 빈도가 생성됩니다. SearXNG는 설계상 엔진과 세션을 유지하지 않으며 장기 지속 쿠키를 사용하지 않으므로, 모든 요청은 이전 기록 없이 전달됩니다. 또한, 제공업체는 주소를 재활용하기 때문에 이전 사용자가 수개월 동안 해당 주소로 스크래핑을 수행했을 수 있으며, 이로 인해 귀하가 생성하지 않은 기록이 주소에 남아 있을 수 있습니다.
거부 응답 자체가 항상 명확한 실패로 나타나는 것은 아닙니다. 엔진은 403이나 429 코드를 반환할 수도 있고, HTTP 200 상태 코드와 함께 본문에 챌린지 페이지를 포함하여 응답할 수도 있습니다. 마지막 경우는 많은 사용자를 혼란스럽게 합니다. 상태 코드만 확인하면 엔진이 정상인 것처럼 보이지만, SearXNG는 응답에서 결과를 하나도 찾지 못하기 때문입니다. 이것이 바로 엔진에 curl을 실행하여 상태 줄만 확인하지 말고, 귀하의 인스턴스에서 생성된 오류 보고서를 직접 읽어야 하는 이유입니다.
변경 전 인스턴스가 보고하는 내용을 확인하십시오
아래의 모든 해결책은 실패한 엔진의 이름과 인스턴스가 기록한 실패 원인에서 시작합니다. SearXNG는 이 두 가지 정보를 모두 제공합니다. /stats 페이지에는 엔진별 오류 횟수와 신뢰도가 나열되어 있으며, /stats/errors는 오류 세부 정보를 JSON 형식으로 반환하므로 이를 보관하거나 다음 주 데이터와 비교하기에 더 용이합니다. 평소 해당 인스턴스에 접속할 때 사용하는 브라우저로 이 페이지들을 여십시오.
컨테이너 로그에는 이벤트가 발생할 때마다 동일한 내용이 기록됩니다. 여기서 사용하는 서비스 이름은 컨테이너 문서와 함께 게시된 compose 파일에 정의된 이름이므로, 본인의 설정이 다르다면 해당 이름을 사용하십시오.
docker compose logs -f core로그를 실시간으로 확인하면서 실패하는 검색을 수행하십시오. 검색이 실행됨에 따라 실패한 엔진에 대한 항목이 나타날 것입니다. 엔진 이름과 인스턴스가 출력한 정확한 이유 문자열을 기록해 두십시오. 이 문서를 포함하여 블로그 게시물에 적힌 엔진 이름을 그대로 복사하지 마십시오. 데이터 센터 IP 주소를 차단하는 엔진 목록은 매달 변경되며, 작성자가 겪은 실패가 사용자에게는 발생하지 않을 수도 있고 그 반대일 수도 있습니다.
결과 페이지에 오류가 전혀 표시되지 않는데 결과가 부족하다면 해당 엔진에 대한 display_error_messages을 확인하십시오. 기본값은 true로 설정되어 있으며, 이 옵션을 끈 인스턴스는 필요한 단 하나의 메시지를 숨기고 있을 수 있습니다.
SearXNG가 실패하는 엔진을 재시도하고 일시 중단하는 방법
SearXNG는 응답하지 않는 엔진에 계속해서 요청을 보내지 않습니다. 실패한 엔진은 일시 중단되며, 중단된 동안에는 완전히 건너뜁니다. 이것이 바로 고장 난 엔진이 조용히 사라지는 방식입니다.
이를 제어하는 두 가지 계층이 있으며, 둘 다 settings.yml 내의 search: 아래에 있습니다. 설정을 붙여넣기 전에 현재 실행 중인 버전의 searx/settings.yml을 확인하여 키 이름과 값이 일치하는지 확인하십시오. 릴리스마다 위치가 변경되었으며, 설정 문서 페이지의 예제는 실제 SearXNG가 로드하는 파일보다 더 긴 중단 시간을 보여줄 수 있기 때문입니다. 2026년 10월 17일자 searx/settings.yml 기준으로 기본값은 다음과 같습니다.
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: 604800첫 번째 계층은 타임아웃과 같은 일반적인 실패를 처리합니다. 차단은 ban_time_on_fail 초부터 시작하여 연속적인 실패가 발생할 때마다 증가하며, 최대 max_ban_time_on_fail까지 늘어납니다. 기본 상한선은 2분으로, 문제가 해결되면 불안정한 엔진은 몇 분 내에 스스로 복구됩니다.
두 번째 계층은 이 가이드에서 다루는 실패 유형을 처리합니다. SearXNG가 응답을 일반적인 오류가 아닌 챌린지나 거부로 인식하면 suspended_times에서 일치하는 항목을 적용하며, 대부분의 수치는 훨씬 큽니다. 180초는 단순 거부나 429 오류에 대한 3분입니다. 3600은 일반적인 CAPTCHA에 대한 1시간입니다. 86400은 하루 전체입니다. 604800은 일주일입니다. 1296000은 15일입니다. cf_ 접두사가 붙은 키는 챌린지가 Cloudflare로 인식될 때 적용되며, recaptcha_은 reCAPTCHA로 인식될 때 적용됩니다.
이것이 가장 많은 시간을 낭비하게 만드는 증상을 설명합니다. 원인을 찾아 수정해도 엔진은 여전히 1시간 동안, 혹은 Cloudflare 챌린지 이후 며칠 동안 아무런 응답을 하지 않습니다. 여전히 일시 중단 상태이기 때문입니다. 중단 상태는 실행 중인 프로세스에 유지되므로 컨테이너를 재시작하면 중단이 해제되고 다음 검색 시 엔진을 다시 시도합니다. 단순 재시작으로 충분하며, 이유 없이 이미지를 다시 빌드하기 전에 재시작으로 충분한 경우와 컨테이너를 다시 생성해야 하는 경우를 알아두는 것이 좋습니다. 재시작 직후 엔진이 다시 실패한다면 수정 작업이 효과가 없었던 것입니다.
엔진별 설정 중 하나는 주의가 필요합니다. retry_on_http_error는 나열된 상태 코드로 엔진이 응답할 때 요청을 재시도합니다. 사용자를 차단하는 엔진에 대해 재시도하면 이미 서버를 봇으로 판단한 시스템에 더 많은 트래픽을 보내게 됩니다. 엔진이 실제로 간헐적으로 작동하는 경우를 해결하려는 것이 아니라면 이 설정을 그대로 두십시오.
SSH 터널 상위 문서와 해결하지 못하는 문제
2026년 10월 17일 확인된 SearXNG 관리자 문서에 따르면, 이 문제는 수동 터널을 통해 해결합니다. 서버를 통해 SOCKS 프록시를 열고, 데스크톱 브라우저를 해당 프록시에 연결한 뒤, 엔진이 서버 주소를 인식하는 동안 직접 챌린지를 해결하는 방식입니다.
ssh -q -N -D 8080 user@example.org-D 8080는 SSH 연결을 통해 전달되는 로컬 SOCKS 서버를 8080 포트에 엽니다. -N은 원격 명령을 실행하지 않으며 -q은 출력을 억제하므로, 정상적인 터널은 아무것도 출력하지 않고 종료되지 않습니다. 두 번째 터미널에서 다음을 확인하십시오.
curl -x socks://127.0.0.1:8080 http://ipecho.net/plain
curl http://ipecho.net/plain첫 번째 명령은 서버 주소를, 두 번째 명령은 데스크톱 주소를 출력해야 합니다. 두 결과가 동일하다면 요청이 터널을 통과하지 않는 것입니다. 이후 브라우저 네트워크 설정에서 SOCKS5 프록시를 127.0.0.1의 8080 포트로 설정하고, 브라우저에서 동일한 주소 확인 페이지를 불러와 서버 주소가 표시되는지 확인한 뒤, 챌린지를 요구하는 엔진에 접속하여 챌린지를 해결하십시오.
이제 솔직한 한계점을 말씀드리겠습니다. 이 방법에는 네 가지 제약이 있습니다. 엔진이 발급하는 쿠키는 데스크톱 브라우저에 저장되는데, SearXNG는 브라우저 쿠키에 접근할 수 없으므로 인스턴스에 도움이 되는 유일한 방법은 엔진이 해당 IP 주소에 대해 기록하는 정보뿐입니다. 이 기록은 엔진이 정한 비공개 일정에 따라 만료됩니다. 이 절차는 자동화되지 않으므로 다음번에 다시 직접 수행해야 합니다. 또한 다른 사용자가 함께 사용하는 인스턴스라면 챌린지를 유발한 쿼리 속도가 여전히 유지되므로 챌린지는 다시 나타납니다.
이 방법은 오늘 오후에 인스턴스 하나를 정상화하는 용도로만 사용하십시오. 이 방식을 기반으로 인스턴스를 구축해서는 안 됩니다.
지속적인 해결책: 차단하는 엔진 제거 또는 가중치 조정
가장 저렴하고 확실한 해결책은 서버에 응답하지 않는 엔진에 쿼리를 보내지 않는 것입니다. settings.yml는 컨테이너 이미지 내의 use_default_settings: true에서 시작합니다. 즉, name과 일치하는 engines: 항목을 설정하면 나열한 키만 재정의되고 나머지 기본 설정은 그대로 유지됩니다.
use_default_settings: true
engines:
- name: <engine name from your stats page>
disabled: true
- name: <another engine name>
weight: 0.3disabled: true은 기본적으로 엔진을 끄지만 환경 설정 페이지에는 남겨두므로, 사용자가 원하면 자신의 검색을 위해 다시 켤 수 있습니다. inactive: true는 사용자 설정에서 해당 엔진을 완전히 제거하며, 서버 주소에서 절대 작동하지 않는 엔진을 처리할 때 적합합니다. weight은 다른 역할을 수행합니다. SearXNG가 결과를 병합하고 순위를 매길 때 해당 엔진의 결과가 반영되는 비중을 조정합니다. 따라서 가중치를 1 미만으로 설정하면 엔진을 완전히 제거하지 않으면서도 중요도가 낮은 엔진이 첫 페이지를 차지하지 않도록 제어할 수 있습니다.
수정 후 컨테이너를 재시작하고 검색을 몇 번 수행한 다음, /stats을 다시 확인하십시오. 오류로 가득 찬 20개의 엔진보다 정상적으로 작동하는 6개의 엔진으로 구성된 깔끔한 통계 페이지가 훨씬 유용합니다.
지속적인 해결책: 프록시를 통한 아웃바운드 요청 전송
SearXNG는 엔진으로 보내는 아웃바운드 요청을 프록시를 거쳐 전송할 수 있으며, 이를 통해 엔진이 인식하는 IP 주소를 변경할 수 있습니다. outgoing:에서 전역으로 설정하거나, 특정 엔진에만 문제가 있는 경우 엔진별로 설정하십시오.
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프록시가 호스트 이름을 해석하게 하려면 socks5://보다 socks5h://을 사용하는 것이 좋습니다. h를 사용하면 호스트 이름이 서버에서 조회되지 않고 프록시로 직접 전달되기 때문입니다. 이와 동시에 타임아웃 제한 시간도 늘려야 합니다. request_timeout의 기본값은 3.0초인데, 프록시를 사용하면 모든 요청에 왕복 시간이 추가되므로 기존에 정상 응답하던 엔진이 타임아웃으로 실패할 수 있습니다. extra_proxy_timeout는 바로 이러한 상황을 위해 존재하며, 프록시 사용 시 타임아웃 시간을 초 단위로 추가합니다. 이 값은 10와 같이 정수로 작성하십시오. 소수점을 허용하는 request_timeout과 달리 extra_proxy_timeout은 설정 스키마에서 정수형으로 정의되어 있습니다. 따라서 문서의 주석 예시와 달리 10.0과 같은 값을 입력하면 잘못된 settings.yml로 간주되어 거부됩니다.
프록시 사용 시 고려 사항:
- 프록시 운영자는 귀하의 인스턴스가 어떤 엔진을 언제 조회하는지 알 수 있습니다. TLS(전송 계층 보안) 덕분에 검색어는 암호화된 요청 내부에 포함되어 로그에 남지 않지만, 트래픽의 형태와 타이밍은 프록시 운영자가 파악할 수 있습니다.
- 공유 출구 IP 주소는 같은 프록시를 사용하는 다른 사람들과 공유됩니다. 만약 다른 사용자가 웹 스크래핑을 수행한다면, 귀하의 인스턴스도 그들의 평판을 그대로 물려받게 되며, 이는 차단을 피하려던 의도보다 더 빠르게 차단으로 이어질 수 있습니다.
- 저렴한 주거용 프록시 풀은 종종 소유자가 트래픽 전달에 동의하지 않은 일반 사용자 기기로 구성됩니다. 구매하는 서비스의 출처를 확인하십시오.
using_tor_proxy: true은 Tor를 통해 라우팅되지만, Tor 출구 노드 주소는 전체 공개되어 있습니다. 데이터 센터 IP 대역을 차단하는 엔진은 보통 출구 노드도 엄격하게 차단합니다.- 이제 검색 기능이 서버 외부 서비스에 의존하게 되므로, 해당 서비스의 장애가 곧 귀하의 검색 결과 장애로 이어질 수 있습니다.
프록시는 차단을 제거하는 것이 아니라 위치를 옮길 뿐이며, 인스턴스의 개인정보 보호 정책에 제3자가 포함되게 됩니다. 짧은 개인정보 보호 정책 때문에 직접 호스팅을 선택한 것이라면, 서비스를 이용하기 전에 직접 호스팅하는 인스턴스가 실제로 숨기는 것과 그렇지 않은 것을 신중히 비교해 보십시오.
지속 가능한 해결책: 의도적으로 더 적은 엔진 세트 운영하기
대부분의 사용자가 간과하는 선택지는 더 적은 수의 엔진을 사용하는 것입니다. SearXNG의 가치는 결과 병합에 있으며, 매번 응답하는 6개의 엔진을 병합하는 것이 절반은 몇 시간 또는 며칠씩 중단되는 20개의 엔진보다 낫습니다. 일주일 동안 /stats를 모니터링하고, 본인의 IP 주소에서 기록이 깨끗한 엔진들만 유지하십시오.
API 키를 사용하여 인증하는 엔진은 다르게 동작합니다. 엔진이 사용자가 누구인지 식별하므로, 사람이 검색하는지 추측하는 대신 할당량을 강제로 적용하기 때문입니다. 이 경우 계정 생성, 설정 파일에 키 저장, 그리고 대개 비용 지불이 수반됩니다. 본인에게 중요한 한두 개의 엔진에 대해서는 이것이 가장 번거로움이 적은 방법인 경우가 많습니다.
다른 도구들을 고려하여 이 결정을 내리십시오. API를 통해 결과를 읽어오는 도구 입장에서는 중단된 엔진이 보이지 않습니다. Open WebUI 및 유사 도구가 쿼리하는 JSON API는 오류를 반환하는 대신 단순히 더 적은 결과를 반환하므로 도구가 이를 감지하기 어렵기 때문입니다. 자동화된 서비스가 본인의 인스턴스에 의존하고 있다면, 누군가 검색 품질이 떨어졌다고 불평하기를 기다리지 말고 주기적으로 /stats/errors를 폴링하십시오.
이 문제를 해결할 가치가 있는가?
사용자 수를 세어 보면 답을 알 수 있습니다. 한 사람을 위한 인스턴스는 하루에 몇 번의 검색 요청을 한 주소에서 보낼 뿐이며, 많은 검색 엔진이 이를 문제 삼지 않습니다. 만약 특정 엔진이 차단을 시도한다면 해결책은 간단합니다. 해당 엔진을 목록에서 제거하십시오. 그러면 그 엔진이 사라졌는지조차 거의 느끼지 못할 것입니다. 이것이 소규모 VPS에서 직접 SearXNG를 운영하는 일반적인 경험이며, 별도의 터널이나 프록시도 필요하지 않습니다.
공용 또는 공유 인스턴스는 같은 소프트웨어를 실행하더라도 상황이 다릅니다. 쿼리 발생 빈도가 차단의 원인이며, 사용자를 추가할 때마다 빈도가 증가하므로 어떤 설정을 하더라도 차단 메시지가 더 빨리 도착하게 됩니다. 처음부터 더 적은 수의 엔진을 사용하도록 계획하고, 지금 추가하는 모든 프록시가 다른 사람들의 검색 요청을 귀하의 계정으로 전달한다는 점을 기억하십시오.
자동화된 클라이언트는 그 중간에 위치하며 더 어려운 경우에 해당합니다. 하나의 질문에 답하기 위해 여러 번 검색을 수행하는 에이전트는 사람이 만들 수 없는 검색 폭주를 유발하므로, 코딩 에이전트나 연구 도구가 가리키는 인스턴스는 사람이 직접 사용하는 동일한 인스턴스보다 더 빨리 차단에 직면합니다. 이러한 용도로 사용한다면 엔진의 다양성보다는 신뢰성을 기준으로 엔진 세트를 선택하고, 에이전트가 실제로 얻을 수 있는 결과물로 작업하게 하십시오.
변하지 않는 원칙은 다음과 같습니다. 해당 엔진이 귀하가 직접 호스팅을 하는 이유라면 차단에 대응하여 싸우고, 그렇지 않다면 해당 엔진을 제거하십시오.
FAQ
문제를 해결했는데도 왜 SearXNG 엔진이 결과를 반환하지 않습니까?
엔진이 여전히 일시 중단 상태이기 때문입니다. SearXNG는 엔진으로부터 챌린지나 거부 응답을 받으면 search.suspended_times에 설정된 시간 동안 해당 엔진에 대한 쿼리를 중단합니다. 기본값은 거부 유형에 따라 3분에서 15일까지 다양합니다. 이 중단 상태는 실행 중인 프로세스 메모리에 유지되므로, 컨테이너를 재시작하면 상태가 초기화되어 다음 검색 시 엔진을 다시 시도하게 됩니다. 재시작 직후 엔진이 다시 실패한다면, 적용한 해결책이 유효하지 않은 것입니다.
엔진의 CAPTCHA 오류와 인스턴스가 반환하는 429 오류는 같은 것입니까?
두 오류는 서로 반대 방향에서 발생합니다. 인스턴스에서 브라우저로 보내는 429 오류는 SearXNG 자체의 제한 장치가 요청을 자동화된 것으로 판단하여 발생하는 것이며, 이는 사용자가 직접 설정할 수 있습니다. 반면 CAPTCHA나 차단 오류는 상위 엔진이 서버를 거부하는 것으로, 사용자가 제어할 수 없는 외부 환경에서 결정됩니다. 결과 페이지는 로드되는데 특정 엔진의 결과만 누락된다면 후자의 경우입니다.
서버에 VPN이나 프록시를 사용하면 엔진 CAPTCHA 문제를 해결할 수 있습니까?
일부 해결될 수 있으나 비용이 발생합니다. outgoing.proxies를 통해 나가는 요청을 라우팅하면 엔진이 인식하는 IP 주소가 변경되므로, 데이터센터 대역에 걸린 차단을 해제할 수 있습니다. 하지만 프록시 운영자가 사용자의 쿼리 내용과 시점을 파악할 수 있게 되며, 다른 사용자와 공유하는 출구 IP를 사용하므로 해당 IP의 평판에 영향을 받습니다. 또한 request_timeout과 extra_proxy_timeout 값을 높이지 않으면 추가된 지연 시간으로 인해 타임아웃이 발생할 수 있습니다. Tor는 using_tor_proxy를 통해 사용할 수 있지만, 출구 노드 주소는 이미 공개되어 있어 챌린지가 자주 발생합니다.
SearXNG가 자동으로 CAPTCHA를 해결하게 할 수 있습니까?
이를 위한 설정은 존재하지 않습니다. 프로젝트에서 권장하는 방법은 수동 방식입니다. SSH SOCKS 터널을 통해 자신의 브라우저로 직접 챌린지를 해결해야 합니다. 챌린지를 자동으로 해결하기 위해 구축하는 모든 도구는 엔진의 정책에 위배되며, 챌린지 방식이 변경될 때마다 작동이 중단됩니다. 결과적으로 검색 인스턴스를 운영하는 대신 스크레이퍼를 유지보수하는 상황에 놓이게 됩니다. 자신의 IP 주소를 차단하는 엔진을 목록에서 제거하는 것이 가장 확실한 해결책입니다.