-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Description
Versions
- Harbor version: v2.13.4 (also confirmed on v2.13.5)
- Infrastructure: Podman (rootless), Ubuntu 24.04
- Installation method: Manual / customized deployment (external Nginx reverse proxy)
- Registry version:
registry-photon:v2.13.4(distribution/distribution v2.8.3)
Description
After upgrading to Harbor v2.13.x, pushed images no longer appear in the Web UI or via the API. The docker push command completes successfully, and images can be pulled from another machine, but they are never registered in Harbor's database.
The root cause is a regression introduced in v2.13.x where the registry notification endpoint was moved from /service/notifications to /registry/notifications, but the CSRF middleware skipper (csrfSkipper) was not updated to exempt the new path.
As a result, every push notification sent by harbor-registry to harbor-core is rejected with:
{"errors":[{"code":"FORBIDDEN","message":"CSRF token not found in request"}]}Since the notification is never processed, harbor-core never writes the artifact to the database → the image is invisible in the UI and API.
Steps to Reproduce
- Deploy Harbor v2.13.x (tested on v2.13.4 and v2.13.5)
- Configure
registry_config.ymlwith the current notification endpoint:
notifications:
endpoints:
- name: harbor
disabled: false
url: http://harbor-core:8080/registry/notifications
headers:
Authorization: [Harbor-Secret <your-secret>]
timeout: 3000ms
threshold: 5
backoff: 1s- Push any Docker image to Harbor:
docker push harbor.example.com/library/myimage:latest- Check Harbor Web UI or API → image is not listed
- Pull the same image from another machine → works fine (blobs exist on disk)
Expected Behavior
The pushed image should appear in the Harbor Web UI and API immediately after a successful docker push.
Actual Behavior
harbor-registry sends a POST /registry/notifications to harbor-core, but receives 403 FORBIDDEN due to CSRF protection. The registry logs show:
level=error msg="retryingsink: error writing events: httpSink{http://harbor-core:8080/registry/notifications}: response status 403 Forbidden unaccepted, retrying"
level=warning msg="httpSink{http://harbor-core:8080/registry/notifications} encountered too many errors, backing off"
Direct curl test from inside harbor-core confirms the issue:
curl -X POST http://localhost:8080/registry/notifications \
-H "Content-Type: application/vnd.docker.distribution.events.v1+json" \
-H "Authorization: Harbor-Secret <secret>" \
-d '{"events":[]}'
# Returns: 403 {"errors":[{"code":"FORBIDDEN","message":"CSRF token not found in request"}]}Note: /api/v2.0/ping returns 200 OK — harbor-core is running correctly. The issue is exclusively the missing CSRF exemption for /registry/.
Additional Notes
- The issue is present in both v2.13.4 and v2.13.5 (v2.13.5 release notes do not mention any fix for this)
- The old endpoint
/service/notificationsreturns 404 in v2.13.x — the route no longer exists - This bug only manifests in custom/manual deployments; the official Harbor installer may generate a config that masks the issue
- A temporary workaround is to deploy a CSRF relay proxy between
harbor-registryandharbor-core - Affected functionality: artifact registration after push, repository listing, image visibility in UI and API
Environment
OS: Ubuntu 24.04
Container runtime: Podman
Harbor core image: docker.io/goharbor/harbor-core:v2.13.4
Registry image: docker.io/goharbor/registry-photon:v2.13.4
Database: PostgreSQL
Proxy: External Nginx (custom config)