The bug where Jetpack refused to connect when my dev workstation was on a VPN and the OAuth rebind steps that re-established the link
It started out like any normal day. Coffee. Boot up the dev workstation. Open a browser tab and head to localhost for some WordPress plugin testing. But then—*bam!* Jetpack hit me with an error. “Unable to connect to WordPress.com”. Wait, what? Everything was fine yesterday.
TLDR
Table of Contents
Jetpack wouldn’t connect to WordPress.com because my dev machine was behind a VPN. The OAuth handshake failed silently. I had to unbind the connection, reinitiate the OAuth flow, and make sure tunneling worked correctly for public access. Once I re-established the route to my local environment, Jetpack played nice again.
What is Jetpack and why does it need a connection?
Jetpack is a WordPress plugin by Automattic. It adds lots of cool features like site stats, brute force protection, social media sharing, and even downtime monitoring. But to use most of those features, it needs a connection to WordPress.com.
That connection is authenticated using something called OAuth. It’s basically a secure way for two services to talk to each other without giving away usernames and passwords. Think of it like a secret handshake.
The problem: VPNs are sneaky
When I’m working on client sites or testing code, I keep my dev machine on a VPN. It adds a layer of security. But VPNs can mess with your machine’s visibility to the outside world.
Jetpack needs to call back to your site during the OAuth handshake. If it can’t reach the site (because your VPN is hiding it), then the connection breaks. No stats. No syncing. No magic.
“This site could not be connected. Jetpack encountered an error during connection.”
Step 1: Rule out the obvious stuff
I checked the following first:
- Was my site actually online? (Yes, via
http://localhost). - Was tunneling working? (I use ngrok).
- Did I have a valid WordPress.com login? (Yes, and cookies too!)
- Was Jetpack on the latest version? (Yup.)
I restarted the site, disabled and re-enabled Jetpack, and even tried switching themes. Nothing helped.
Step 2: Check your tunnel
Jetpack tries to contact your site from the public internet during OAuth setup. If you’re running your site locally behind localhost, that won’t work. So you need a public URL pointing to your local site.
That’s where tools like ngrok help. They create a secure tunnel from the public internet to your local machine. So https://my-project.ngrok.app becomes the temporary public face of your local machine.
Step 3: Update site URLs
This tripped me up for a while.
Even though the tunnel was working, my WordPress site still had its settings pointing to http://localhost. WordPress uses these URLs for pretty much everything—like links, AJAX requests, and API auth endpoints.
I went to:
- Settings → General
…and updated:
- WordPress Address (URL)
- Site Address (URL)
…to my ngrok URL.
https://my-project.ngrok.app
But Jetpack still refused to connect
Cue dramatic music. I clicked “Connect to WordPress.com” and waited.
Redirects happened. OAuth danced. My WordPress.com account authorized access. But then… nothing. Just that familiar error message again.
It wasn’t until I checked the Jetpack debug log that things clicked:
Could not verify your site using the Jetpack XML-RPC endpoint.
Jetpack couldn’t complete the handshake. And yep, the VPN was the culprit.
Step 4: Disconnect and rebind
At this point I tried something desperate—but it worked.
I disconnected Jetpack entirely via:
- Jetpack → Settings
- Scroll all the way down
- Click “Disconnect site from WordPress.com”
Once disconnected, I cleared cookies, logged out of WordPress.com, and reloaded my site using the public ngrok URL.
Then this:
- Clicked Set up Jetpack
- Chose my WordPress.com account again
- Approved all OAuth prompts
This time? It worked. Jetpack was connected. Stats and syncing were back.
Step 5 (optional): Lock it in for development
If you don’t want to go through the unbind/rebind process every day, here’s a trick:
- Keep the same tunneling address. Use a custom subdomain with paid features on tools like ngrok or Cloudflare Tunnel.
- Update your local
hostsfile or use a reverse proxy to mirror that public URL to your internal localhost setup. - Create a small bash script to bring up your tunnel, open your site, and start your dev server in one go.
Bonus tip: Keep Jetpack in development mode locally if you don’t need the cloud features every time. Just add this line in your wp-config.php:
define( 'JETPACK_DEV_DEBUG', true );
This lets Jetpack work offline and skips the connection drama entirely while still letting you test most features.
Lessons learned
- Jetpack is picky about public availability during OAuth. VPNs confuse it.
- ngrok or another tunnel tool is your best friend during local dev that needs Jetpack features.
- Always ensure your site URLs match your public tunnel or handshake will fail silently.
I now have a sticky note on my monitor that reads: “VPN + Jetpack = ??? Check URLs + Tunnel!”
Conclusion
The issue turned out to be a mix of VPN masking and outdated site URLs. It was a frustrating, silent failure. But once I disconnected and initiated a clean OAuth re-bind through a visible tunnel, everything worked.
So next time Jetpack throws you errors out of nowhere, follow this checklist:
- Is your site publicly reachable?
- Do your site URLs match the tunnel address?
- Have you tried disconnecting and reinitiating the OAuth handshake?
And if all else fails, take a breath. Get coffee. Maybe even write an article about it.