Kirby version: 5.3.0
PHP version (production): 8.2.30 (updated to 8.5 during troubleshooting — same issue)
PHP version (local): 8.5.3 (Docker, shinsenter/kirby:latest)
Server: Apache/2.4.66 (Unix) on Strato shared hosting
Browser: Tested in both Safari 26.2 and Chrome — same behavior in both
Description
When editing any page in the Panel on my production server (Strato shared hosting), any content change — even typing a single character in a text field — triggers the following error:
{
"status": "error",
"message": "No route found for path: \"pages/projects+porject-name/changes/save\" and request method: \"GET\"",
"code": 404,
"exception": "Exception",
"key": null,
"file": "kirby/src/Http/Router.php",
"line": 191
}
The issue does not occur locally using Docker (shinsenter/kirby:latest). Only on the Strato shared hosting server.
Root cause observation
Looking at the browser Network tab, the Panel sends a GET request to the changes/save endpoint instead of a POST:
Failing request (affected pages):
URL: https://example.com/api/pages/projects+some-project/changes/save
Request Method: GET
Status Code: 404 Not Found
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Working request (other pages on the same site):
URL: https://example.com/api/pages/projects+polygarden/changes/save
Request Method: POST
Status Code: 200 OK
The key detail: the failing request has Sec-Fetch-Dest: document and Sec-Fetch-Mode: navigate, meaning the browser is performing a full page navigation rather than an AJAX/fetch POST call. This suggests the original POST request is being redirected (301/302) by the server, and the browser follows the redirect as a GET — which then fails because changes/save is only registered as a POST route.
What I checked
-
.htaccess: Standard Kirby.htaccessis in place, unmodified. No trailing slash redirect, no HTTP-to-HTTPS rewrite. I even tested with the.htaccessmissing entirely — same error. -
File permissions: The affected project folders had
_changesdirectories with750permissions. Deleting the_changesfolders and re-uploading the content resolved the issue temporarily, but it eventually came back. -
Plugins: I have
pechente/kirby-password-guardinstalled. I setenabled: falsein the config and the issue persisted, ruling out the plugin as the cause. -
PHP version: Started with PHP 8.2.30, upgraded to 8.5 on the server — no change.
-
Browsers: Reproduced in both Safari and Chrome.
-
Local environment: Cannot reproduce locally in Docker at all. Same codebase, same Kirby version.
Pattern
-
The issue only occurs on the Strato shared hosting server, never locally
-
Initially it only affected specific projects (those that had existing
_changesfolders with restrictive permissions), but eventually affected all projects -
Deleting
_changesfolders from the server temporarily fixes it until Kirby recreates them -
Pages that have never been edited (no
_changesfolder yet) work fine until the first_changesfolder is created -
The
_changesfolders created by Kirby on the server get750permissions, which may be too restrictive for the web server process
Suspicion
I believe the issue is related to how the _changes directory is created on shared hosting. When Kirby creates the _changes folder, it gets 750 permissions on my Strato server. If the Apache/PHP process cannot write to this directory on subsequent requests (e.g., due to a user/group mismatch), the write operation fails, and the Panel’s error handling causes a browser navigation (GET) instead of gracefully handling the error in the AJAX response.
The fact that freshly uploaded content (without _changes folders) works fine, and then breaks once Kirby creates the _changes directory, supports this theory.
Steps to reproduce
-
Deploy a Kirby 5.3.0 site to Strato shared hosting (Apache 2.4.66)
-
Create/edit a page in the Panel
-
Wait for Kirby to create the
_changesdirectory -
Edit the same page again — type a single character in any text field
-
Observe the 404 error in the browser console
Expected behavior
The Panel should send a POST request to changes/save and receive a 200 response.
Actual behavior
The Panel sends a GET request (browser navigation) to changes/save, which returns a 404 because no GET route exists for that path.
Workaround
Manually deleting _changes folders from the server and setting directory permissions to 755 or 775 temporarily resolves the issue until Kirby recreates them.