How to Sync Nextcloud Calendar with Google Calendar

By Rida F'kih · August 11, 2026

Your Nextcloud calendar holds your real life. Google Calendar holds your work. Neither one knows the other exists, so people book meetings over your evenings.

Keeper.sh signs into both calendars and keeps copies of your events in step. It takes about ten minutes.

What does this actually do?

Add an event in Nextcloud and a copy appears on your Google calendar. Move it, and the copy moves. Delete it, and the copy disappears.

By default the copy is a block of busy time, not a readable event. Your coworkers see that you are unavailable, not what you are doing.

Copies travel one way per connection: Nextcloud to Google, or Google to Nextcloud. Want both? That is one connection each way, not a single "two-way" switch.

What you need before you start

  • A Nextcloud server you can reach over the internet
  • Your Nextcloud username, and your password or an app password
  • A Google account
  • A free account on keeper.sh

If two-factor login is switched on in Nextcloud, your normal password will not work here. An app password is a second password that only reaches your calendar and can be cancelled on its own. Make one under Settings → Security → Devices & sessions.

How do you connect Nextcloud?

From the dashboard, click Import Calendars, then Connect CalDAV Server at the bottom of the list. Nextcloud has no button of its own — it speaks the same calendar standard as Google and Outlook.

The page is headed Connect CalDAV Server and has three boxes:

  1. CalDAV Server URL — your Nextcloud web address, like https://cloud.example.com
  2. CalDAV Server Username — your Nextcloud username, which is often not your email address
  3. CalDAV Server Password — your password, or the app password you just made

Use the plain web address. Keeper.sh asks the server where your calendars live, so you do not need the long remote.php/dav/ path.

Click Connect. Every calendar it found is imported at once, and you land in a short setup flow.

How do you connect Google Calendar?

Go back to Import Calendars and click Connect Google Calendar. The page is headed Connect Google and lists what it will ask Google for before it sends you anywhere.

Click Connect and approve it on Google's own screen. Keeper.sh never sees your Google password.

How do you tell Keeper.sh which way events travel?

The setup flow asks four things, word for word:

  1. Which calendars would you like to configure? Tick the ones you care about now.
  2. Rename Your Calendars. Nextcloud calendars arrive as "Personal", Google's as your email address. Renaming only changes what you see in Keeper.sh.
  3. Where should 'Personal' send events? Tick Google, and copies of your Nextcloud events start appearing there.
  4. Where should 'Personal' pull events from? Tick Google here to get the reverse.

Each tick is one connection. Ticking both directions is two connections, not one.

You can change all of this later. Open the calendar under Calendars and use the Send Events to Calendars section.

Will people see my private event titles?

Check this yourself before you trust it. Open the calendar under Calendars and find Sync Settings. Three switches decide what travels: Sync Event Name, Sync Event Description and Sync Event Location.

Calendars you add through Import Calendars arrive with all three off. Your dentist appointment reaches Google as a block named after the calendar it came from. Turn Sync Event Name on and real titles come through, using the Event Name box, which understands {{calendar_name}} and {{event_name}}.

On Keeper.sh these switches are a Pro feature. The dashboard says so: Advanced sync settings are a Pro feature.

Below them, Exclusions can drop Exclude All Day Events. Google calendars also offer Exclude Focus Time Events and Exclude Out of Office Events.

How fast do changes show up?

Keeper.sh reads both calendars every minute, on every plan. Getting that change onto the other calendar depends on your plan: up to thirty minutes on free, about a minute on Pro.

If you are blocking out evenings so nobody books them, thirty minutes changes nothing. If people book you through a scheduling link, it is too slow. Do not pay for speed you will not notice.

What does not come across?

Guest lists, video call links and reminders do not travel at all. So a copied meeting is a block of time, not a working invite — you cannot join the call from it, and nobody else gets notified. Guest lists are read only to show you invitations you have not replied to yet.

Keeper.sh also looks at a fixed stretch of time — from a week ago to two years ahead. A one-off event further out than that is not copied. A repeating event that started before the window is still picked up, so its dates inside the window survive.

What goes wrong, and what does it look like?

The page says "Invalid credentials". Keeper.sh reached your Nextcloud, and Nextcloud turned it away. Almost always this is two-factor login, which stops your normal password working here. Use an app password instead, and check the username too.

The page says "Failed to discover calendars". This means something different. Keeper.sh never got a usable answer from the address you gave, so your username and password were never tested. Check the web address for a typo, and confirm the server is reachable from outside your own network.

The page says "No calendars found". Your credentials worked, but Keeper.sh found nothing to import at that address. Try the longer remote.php/dav/calendars/username/ form instead.

One bad repeating event freezes a whole calendar. Not one missing event — everything stops updating. Keeper.sh refuses to work through a repeating series producing more than 10,000 dates in two years, and today that stops the whole calendar. Delete the event repeating every minute or hour and it catches up.

Events vanish from Google that still exist in Nextcloud. Keeper.sh reads your whole Nextcloud calendar each time. If something in front of it caps how much comes back in one response, Keeper.sh sees a shorter calendar and removes the difference. A reverse proxy with a tight response limit does this.

There is no "sync now" button. You wait for the next round. Removing the account and adding it again is the blunt way to start clean.

What does the free plan cover?

Two calendar accounts and three connections. Nextcloud is one account no matter how many calendars it holds, and Google is the second, so this pairing uses both. Adding Outlook later means upgrading.

Three connections covers both directions here with one to spare. There is no cap on how many calendars an account brings in.

Do you want to run Keeper.sh yourself?

Keeper.sh is open source under AGPL-3.0, and self-hosting is a genuine option rather than a consolation prize. Every Pro feature is included. It is a Docker Compose stack with Postgres and Redis behind it.

You already run Nextcloud, so you know the cost: a server, a domain, upgrades, backups, and being the one who gets paged at 7am.

One setting matters here. BLOCK_PRIVATE_RESOLUTION stops Keeper.sh fetching anything on a private network, and deploy/compose.yaml turns it on for the api and cron services. PRIVATE_RESOLUTION_WHITELIST is the escape hatch:

BLOCK_PRIVATE_RESOLUTION=true
PRIVATE_RESOLUTION_WHITELIST=192.168.1.50,nextcloud.local

Set both on api and cron, and whitelist the exact address you will paste into the connect form. Skip it and the connect page says Failed to discover calendars, without telling you why — the reason only appears in the logs.

On hosted Keeper.sh neither setting can change, so your Nextcloud has to be reachable from the internet.

How do you cut access off?

Delete the app password in Nextcloud, or delete the account under Calendar Sources in the dashboard.

Keeper.sh stores that password in a form it can read back, because this kind of connection sends it on every request. It is encrypted before storage, with a key you control if you self-host.

Can Keeper.sh use cookies for analytics?