{"id":25045,"date":"2026-08-08T17:17:28","date_gmt":"2026-08-08T17:17:28","guid":{"rendered":"https:\/\/capskip.com\/?p=25045"},"modified":"2026-08-11T19:22:44","modified_gmt":"2026-08-11T19:22:44","slug":"error-key-does-not-exist","status":"publish","type":"post","link":"https:\/\/capskip.com\/zh\/error-key-does-not-exist\/","title":{"rendered":"\u5982\u4f55\u4fee\u590d ERROR_KEY_DOES_NOT_EXIST \u4e0e Wrong User Key \u9519\u8bef"},"content":{"rendered":"<p>Short answer: <code>ERROR_KEY_DOES_NOT_EXIST<\/code> means the API key in your request is not a key the solver recognises. Nothing is wrong with the CAPTCHA, the sitekey or the page URL. The request never got as far as being solved. This guide covers the three things that actually cause it, the fix in all four SDKs, and why you sometimes get <code>ERROR_WRONG_USER_KEY<\/code> instead.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">What ERROR_KEY_DOES_NOT_EXIST means<\/h2>\n<p>It comes back from <code>\/in.php<\/code>, at submit time, before any solving starts. The API compared the <code>key<\/code> parameter in your request against the key it is configured to accept, and did not find a match.<\/p>\n<pre data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\"># Submitting with a key the app does not know:\ncurl &quot;http:\/\/127.0.0.1:8080\/in.php?key=WRONG&amp;method=userrecaptcha&amp;googlekey=YOUR_SITEKEY&amp;pageurl=https:\/\/example.com&quot;\n\nERROR_KEY_DOES_NOT_EXIST<\/pre>\n<p>Because it is returned at submit time you never get a captcha ID, so there is nothing to poll for on <code>\/res.php<\/code>. If your code is looping and waiting, it is waiting on an ID that was never issued.<\/p>\n<p>One thing that trips people up coming from a hosted service: CapSkip is a <a href=\"https:\/\/capskip.com\/2captcha-api-alternative\/\">2captcha-compatible API that runs on your own machine<\/a>, so the key is not an account credential and it is not tied to a balance. It is a local access check on the API server. That changes what &#8220;wrong key&#8221; can even mean, which is why the fixes below are short.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">First, check whether key validation is even on<\/h2>\n<p>CapSkip ships with key validation optional. When it is off, any non-empty string works and you will never see this error. When it is on, the key has to match exactly.<\/p>\n<p>Open the CapSkip app, go to Settings, and look at the API server section. Two things matter there: whether key validation is enabled, and the exact key string if it is. Copy the key from that screen rather than retyping it. Most reports of <code>ERROR_KEY_DOES_NOT_EXIST<\/code> end here.<\/p>\n<p>While you are in Settings, confirm the port too. A wrong port gives you a connection error rather than this one, but it is worth checking both at the same time. The <a href=\"https:\/\/capskip.com\/setup-guide\/\">setup guide<\/a> walks through the whole screen.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Pass the key correctly in each SDK<\/h2>\n<p>All four SDKs take the same option name, and all four read the same environment variable, <code>CAPSKIP_API_KEY<\/code>. Set it explicitly while you are debugging so there is no doubt about what is being sent.<\/p>\n<pre data-enlighter-language=\"python\" class=\"EnlighterJSRAW\"># pip install capskip\nfrom capskip import CapSkip\n\n# apiKey defaults to &quot;capskip&quot;, which only works when\n# key validation is turned off in the app.\nsolver = CapSkip(\n    apiKey=&quot;YOUR_API_KEY&quot;,\n    host=&quot;127.0.0.1&quot;,\n    port=8080,\n)<\/pre>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\/\/ npm install capskip\nconst { CapSkip } = require('capskip');\n\nconst solver = new CapSkip({\n  apiKey: 'YOUR_API_KEY',\n  host: '127.0.0.1',\n  port: 8080,\n});<\/pre>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\/\/ composer require capskip\/capskip\nuse CapSkip\\CapSkip;\n\n$solver = new CapSkip([\n    'apiKey' =&gt; 'YOUR_API_KEY',\n    'host'   =&gt; '127.0.0.1',\n    'port'   =&gt; 8080,\n]);<\/pre>\n<pre data-enlighter-language=\"csharp\" class=\"EnlighterJSRAW\">\/\/ dotnet add package CapSkip\nusing CapSkip;\n\nvar solver = new CapSkipClient(\n    apiKey: &quot;YOUR_API_KEY&quot;,\n    host:   &quot;127.0.0.1&quot;,\n    port:   8080);<\/pre>\n<p>Full signatures for every method are on the <a href=\"https:\/\/capskip.com\/captcha-solving-sdk\/\">CAPTCHA solving SDK<\/a> page.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">The three causes worth checking<\/h2>\n<h3 style=\"font-size:1.3rem;line-height:1.4;\">1. The key never left your code<\/h3>\n<p>You set <code>CAPSKIP_API_KEY<\/code> in a <code>.env<\/code> file, but nothing loads <code>.env<\/code> at runtime. Or you exported it in one shell and ran the script in another. The SDK falls back to its default, the default is not your key, and you get the error.<\/p>\n<p>Print what you are about to send. One line, and it settles the question:<\/p>\n<pre data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">import os\n\n# Never print the whole key in a shared log.\nkey = os.environ.get(&quot;CAPSKIP_API_KEY&quot;, &quot;&lt;unset&gt;&quot;)\nprint(len(key), repr(key[:4]))<\/pre>\n<p>Printing the length catches the case a masked value hides: a key that is present but empty, or one carrying a trailing newline from <code>cat key.txt<\/code>.<\/p>\n<h3 style=\"font-size:1.3rem;line-height:1.4;\">2. The key is right but mangled in the URL<\/h3>\n<p>This only bites people calling the raw API. If your key contains characters with a meaning in a query string, they have to be percent-encoded. A <code>+<\/code> becomes a space, a <code>&amp;<\/code> ends the parameter early, and a <code>#<\/code> truncates everything after it.<\/p>\n<pre data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\"># Wrong: curl sends this raw and the key gets cut at the &amp;\ncurl &quot;http:\/\/127.0.0.1:8080\/in.php?key=ab&amp;cd&amp;method=userrecaptcha&quot;\n\n# Right: let curl encode the parameter for you\ncurl -G http:\/\/127.0.0.1:8080\/in.php \\\n  --data-urlencode &quot;key=ab&amp;cd&quot; \\\n  --data-urlencode &quot;method=userrecaptcha&quot;<\/pre>\n<p>Or POST the parameters as a form body instead, which sidesteps the whole class of problem. MDN has a short reference on <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Glossary\/Percent-encoding\" rel=\"nofollow noopener\" target=\"_blank\">percent-encoding<\/a> if you want the exact character list. The SDKs encode for you, so this cause disappears the moment you switch to one.<\/p>\n<h3 style=\"font-size:1.3rem;line-height:1.4;\">3. You changed the key and something is still holding the old one<\/h3>\n<p>A long-running worker, a Docker container built with the key baked in, a CI secret, a browser extension configured separately. The app has the new key, one caller still has the old one, and only that caller fails. If some of your requests work and others do not, this is almost always it.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">ERROR_KEY_DOES_NOT_EXIST vs ERROR_WRONG_USER_KEY<\/h2>\n<p>Two error strings, same family. Treat them as one problem with two shapes.<\/p>\n<table>\n<thead>\n<tr>\n<th>Error<\/th>\n<th>What it points at<\/th>\n<th>First thing to check<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>ERROR_KEY_DOES_NOT_EXIST<\/code><\/td>\n<td>The key was read and did not match a known key<\/td>\n<td>The key string itself, copied from Settings<\/td>\n<\/tr>\n<tr>\n<td><code>ERROR_WRONG_USER_KEY<\/code><\/td>\n<td>Key validation is on and the key sent is wrong<\/td>\n<td>Whether validation is on at all, then the string<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In the SDKs both surface as an <code>ApiException<\/code>, so catch that one type and read the message rather than branching on the string.<\/p>\n<pre data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">from capskip import CapSkip, ApiException, NetworkException\n\nsolver = CapSkip(apiKey=&quot;YOUR_API_KEY&quot;)\n\ntry:\n    result = solver.recaptcha(\n        sitekey=&quot;YOUR_SITEKEY&quot;,\n        url=&quot;https:\/\/example.com\/page-with-recaptcha&quot;,\n    )\nexcept ApiException as e:\n    # Key problems land here, with the raw code in the message.\n    print(&quot;api rejected the request:&quot;, e)\nexcept NetworkException as e:\n    # The app is not running, or the port is wrong.\n    print(&quot;cannot reach capskip:&quot;, e)<\/pre>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Nearby error codes<\/h2>\n<p>If the key checks out, the next few failures at submit time look similar but mean something else entirely.<\/p>\n<table>\n<thead>\n<tr>\n<th>Code<\/th>\n<th>Cause<\/th>\n<th>Fix<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>ERROR_WRONG_METHOD<\/code><\/td>\n<td>The <code>method<\/code> parameter is missing or misspelled<\/td>\n<td>Use <code>userrecaptcha<\/code>, <code>turnstile<\/code>, <code>geetest<\/code>, <code>post<\/code> or <code>base64<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>ERROR_BAD_PARAMETERS<\/code><\/td>\n<td>A required parameter for that method is absent<\/td>\n<td>Check the method&#8217;s parameter list before resubmitting<\/td>\n<\/tr>\n<tr>\n<td><code>ERROR_GOOGLEKEY<\/code><\/td>\n<td>The sitekey was rejected<\/td>\n<td>Re-read it from the live page, not from cached source<\/td>\n<\/tr>\n<tr>\n<td><code>ERROR_PAGEURL<\/code><\/td>\n<td>The page URL is missing or malformed<\/td>\n<td>Send the full URL including the scheme<\/td>\n<\/tr>\n<tr>\n<td>Connection refused<\/td>\n<td>The app is not running or the port differs<\/td>\n<td>Start CapSkip, confirm the API server is on<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Every code the API can return is listed in the <a href=\"https:\/\/capskip.com\/api-docs\/\">API documentation<\/a>.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Frequently asked questions<\/h2>\n<details style=\"border:1px solid #e2e5ee;border-radius:10px;padding:14px 18px;margin:0 0 12px;\">\n<summary style=\"cursor:pointer;\">\n<h3 style=\"font-size:1.15rem;line-height:1.4;display:inline;margin:0;\">Do I need an API key at all?<\/h3>\n<\/summary>\n<p style=\"margin:12px 0 0;\">Only if key validation is enabled in the app. With it off, any non-empty string is accepted and the SDK default of <code>capskip<\/code> works fine. The key is a local access check, not an account.<\/p>\n<\/details>\n<details style=\"border:1px solid #e2e5ee;border-radius:10px;padding:14px 18px;margin:0 0 12px;\">\n<summary style=\"cursor:pointer;\">\n<h3 style=\"font-size:1.15rem;line-height:1.4;display:inline;margin:0;\">Can ERROR_KEY_DOES_NOT_EXIST mean I ran out of credit?<\/h3>\n<\/summary>\n<p style=\"margin:12px 0 0;\">No. There is no balance to run out of. Solving happens on your own machine, so a key error is always a mismatch between what you sent and what the app expects.<\/p>\n<\/details>\n<details style=\"border:1px solid #e2e5ee;border-radius:10px;padding:14px 18px;margin:0 0 12px;\">\n<summary style=\"cursor:pointer;\">\n<h3 style=\"font-size:1.15rem;line-height:1.4;display:inline;margin:0;\">Does the key go in the poll request too?<\/h3>\n<\/summary>\n<p style=\"margin:12px 0 0;\">Yes. <code>\/res.php<\/code> takes the same <code>key<\/code> parameter as <code>\/in.php<\/code>. If you only fixed the submit call, the poll can still fail on the old value.<\/p>\n<\/details>\n<details style=\"border:1px solid #e2e5ee;border-radius:10px;padding:14px 18px;margin:0 0 12px;\">\n<summary style=\"cursor:pointer;\">\n<h3 style=\"font-size:1.15rem;line-height:1.4;display:inline;margin:0;\">Why does my old 2captcha key not work here?<\/h3>\n<\/summary>\n<p style=\"margin:12px 0 0;\">Because it was issued by their service and means nothing to a solver running on your machine. The API shape is the same, the credentials are not. Point your client at <code>127.0.0.1<\/code> and use the key from CapSkip Settings.<\/p>\n<\/details>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Summary<\/h2>\n<p>Check whether key validation is on, copy the key from Settings instead of retyping it, confirm the value actually reaches your process, and encode it properly if you are building the URL by hand. That covers effectively every occurrence of <code>error_key_does_not_exist<\/code>.<\/p>\n<p>The whole class of problem gets smaller when the solver is a <a href=\"https:\/\/capskip.com\/\">local captcha solver<\/a> you control: no account, no balance, no rotating credentials, and one key you can read off the screen in front of you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>ERROR_KEY_DOES_NOT_EXIST \u662f\u5bc6\u94a5\u4e0d\u5339\u914d\uff0c\u4e0d\u662f\u8bc6\u522b\u5de5\u5177\u574f\u4e86\u3002\u4e09\u79cd\u6210\u56e0\u3001\u56db\u4e2a SDK \u4e2d\u5404\u81ea\u7684\u4fee\u6cd5\uff0c\u4ee5\u53ca\u5b83\u548c ERROR_WRONG_USER_KEY \u7684\u533a\u522b\u3002<\/p>","protected":false},"author":1,"featured_media":25173,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Fix ERROR_KEY_DOES_NOT_EXIST in Minutes | CapSkip","rank_math_description":"ERROR_KEY_DOES_NOT_EXIST means the API key in your request is not the one CapSkip is checking. Here is how to confirm it, fix it, and stop it recurring.","rank_math_focus_keyword":"error_key_does_not_exist","footnotes":""},"categories":[70],"tags":[],"class_list":["post-25045","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-captcha"],"_links":{"self":[{"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/posts\/25045","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/comments?post=25045"}],"version-history":[{"count":1,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/posts\/25045\/revisions"}],"predecessor-version":[{"id":25105,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/posts\/25045\/revisions\/25105"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/media\/25173"}],"wp:attachment":[{"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/media?parent=25045"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/categories?post=25045"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/tags?post=25045"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}