Take the 2-minute tour ×

maybe you guys can help me with this. I am trying to implement reCAPTCHA in my node.js application and no matter what I do, I keep getting "invalid-site-private-key" as a response.

Here are the things I double and double checked and tried:

  1. Correct Keys
  2. Keys are not swapped
  3. Keys are "global keys" as I am testing on localhost and thought it might be an issue with that
  4. Tested in production environment on the server - same problem

The last thing I can think of is that my POST request to the reCAPTCHA API itself is incorrect as the concrete format of the body is not explicitly documented (the parameters are documented, I know). So this is the request body I am currently sending (the key and IP is changed but I checked them on my side):

privatekey=6LcHN8gSAABAAEt_gKsSwfuSfsam9ebhPJa8w_EV&remoteip= challenge=03AHJ_Vuu85MroKzagMlXq_trMemw4hKSP648MOf1JCua9W-5R968i2pPjE0jjDGX TYmWNjaqUXTGJOyMO3IKKOGtkeg_Xnn2UVAfoXHVQ-0VCHYPNwrj3PQgGj22EFv7RGSsuNfJCyn mwTO8TnwZZMRjHFrsglar2zQ&response=Coleshill areacce

Is there something wrong with this format? Do I have to send special headers? Am I completely wrong? (I am working for 16 hours straight now so this might be ..)

Thank you for your help!

share|improve this question
Not enough detail provided. What are the request headers? Are you using a module like github.com/mirhampt/node-recaptcha ? Maybe try reposting when you've gotten some sleep. :P –  broofa Sep 17 '11 at 15:20
Hey broofa, sorry that my question was not sufficient to answer it. nevertheless you unintentionally solved my problem b/c in the module you postet the undocumented headers that are necessary to verify a reCAPTCHA are used, so I was able to build them into my own solution. I'll post the solution later as an answer. Thank you! ;) –  florian.k Sep 18 '11 at 8:57
add comment

2 Answers

up vote 11 down vote accepted

As stated in the comments above, I was able to solve the problem myself with the help of broofa and the node-recaptcha module available at https://github.com/mirhampt/node-recaptcha.

But first, to complete the missing details from above:

  • I didn't use any module, my solution is completely self-written based on the documentation available at the reCAPTCHA website.
  • I didn't send any request headers as there was nothing stated in the documentation. Everything that is said concerning the request before they explain the necessary parameters is the following:

    "After your page is successfully displaying reCAPTCHA, you need to configure your form to check whether the answers entered by the users are correct. This is achieved by doing a POST request to http://www.google.com/recaptcha/api/verify. Below are the relevant parameters."

    -- "How to Check the User's Answer" at http://code.google.com/apis/recaptcha/docs/verify.html

So I built a querystring myself (which is a one-liner but there is a module for that as well as I learned now) containing all parameters and sent it to the reCAPTCHA API endpoint. All I received was the error code invalid-site-private-key, which actually (as we know by now) is a wrong way of really sending a 400 Bad Request. Maybe they should think about implementing this then people would not wonder what's wrong with their keys.

These are the header parameters which are obviously necessary (they imply you're sending a form):

  • Content-Length which has to be the length of the query string
  • Content-Type which has to be application/x-www-form-urlencoded

Another thing I learned from the node-recaptcha module is, that one should send the querystring utf8 encoded.

My solution now looks like this, you may use it or built up on it but error handling is not implemented yet. And it's written in CoffeeScript.

http = require 'http'

module.exports.check = (remoteip, challenge, response, callback) ->

  privatekey = 'placeyourprivatekeyhere'

  request_body = "privatekey=#{privatekey}&remoteip=#{remoteip}&challenge=#{challenge}&response=#{response}"
  response_body = ''

  options = 

    host: 'www.google.com'
    port: 80
    method: 'POST'
    path: '/recaptcha/api/verify'

  req = http.request options, (res) ->

    res.setEncoding 'utf8'

    res.on 'data', (chunk) ->
      response_body += chunk

    res.on 'end', () ->
      callback response_body.substring(0,4) == 'true'

  req.setHeader 'Content-Length', request_body.length

  req.write request_body, 'utf8'

Thank you :)

share|improve this answer
I ran into this problem as well, explicitly setting the Content-Type header worked for me, thanks! (Content-Length was already set by my framework). –  Doge Apr 17 '12 at 13:32
You mention that the data must be utf8 encoded. I'm using a PHP based implementation and even in the original library code (v1.11) I can find no mention of this. The original implementation uses $key ."=" . urlencode(stripslashes($value)) but I'm pretty sure http_build_query is a superior alternative, my guess is that they opted not to use it to stay compatible with PHP 4.x. In the original node-recaptcha implementation res.setEncoding('utf8') is not included, did you add this yourself? –  Doge Apr 17 '12 at 13:32
You're right, there is no res.setEncoding('utf8') in node-recaptcha but if you carefully all the way down to line 151 you see that the response is ultimately written to the output stream in utf-8 encoding. I really do not know whether this is crucial but I included it in my solution and it worked. –  florian.k Apr 23 '12 at 8:17
add comment

+1 to @florian for the very helpful answer. For posterity, I thought I'd provide some information about how to verify what your captcha request looks like to help you make sure that the appropriate headers and parameters are being specified.

If you are on a Mac or a Linux machine or have access to one of these locally, you can use the netcat command to setup a quick server. I guess there are netcat windows ports but I have no experience with them.

nc -l 8100

This command creates a TCP socket listening on pot 8100 and will wait for a connection. You then can change the captcha verify URL from http://www.google.com/recaptcha/... in your server code to be http://localhost:8100/. When your code makes the POST to the verify URL you should see your request outputted to the scree by netcat:

Content-Length: 277
Host: localhost:8100
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1 (java 1.5)


Using this, I was able to see that my private-key was corrupted.

share|improve this answer
add comment

Your Answer


