Skip to content

Howto Troubleshoot proxy login

root edited this page Apr 19, 2026 · 1 revision

How to troubleshoot a stuck proxy login

Use this guide when proxy auth mode is configured but login isn't completing — you're stuck at a 401, the wrong page, or an infinite redirect.

Work through the sections in order. Each section has a diagnostic command and a fix.


Step 1 — Confirm Bindery started in proxy mode

# Docker
docker logs bindery 2>&1 | grep -E "trusted proxies|auth mode|proxy"

# Kubernetes
kubectl logs deployment/bindery | grep -E "trusted proxies|auth mode|proxy"

Expected output:

trusted proxies: [172.20.0.0/16]

If you see proxy mode requires BINDERY_TRUSTED_PROXY and Bindery exited: the env var is empty. Add BINDERY_TRUSTED_PROXY to your container/pod config and restart.

If you see no proxy-related log lines: Bindery may not be in proxy mode yet. Check the current auth mode:

curl -s http://bindery:8787/api/v1/auth/status | jq .mode

If the response is not "proxy", set it:

curl -X PUT http://bindery:8787/api/v1/auth/mode \
  -H "X-Api-Key: <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{"mode": "proxy"}'

Step 2 — Verify the identity header is reaching Bindery

Enable debug logging temporarily to see what headers Bindery receives:

# Set log level to debug (no restart needed)
curl -X PUT http://bindery:8787/api/v1/system/loglevel \
  -H "X-Api-Key: <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{"level": "debug"}'

Then make a request through your proxy (from a browser or curl through the proxy URL). Watch the logs:

docker logs -f bindery 2>&1 | grep -i "proxy\|header\|remote-user\|x-forwarded"

What you're looking for:

  • The log should show the identity header being read (e.g. proxy auth header: Remote-User = alice)
  • If the header is absent or empty, the proxy isn't forwarding it — see Step 3

Reset log level when done:

curl -X PUT http://bindery:8787/api/v1/system/loglevel \
  -H "X-Api-Key: <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{"level": "info"}'

Step 3 — Confirm the identity header is being forwarded by the proxy

The most common cause of 401 in proxy mode is the identity header not reaching Bindery.

Check with curl directly (bypassing the proxy)

# Send a request directly to Bindery with a fake identity header from a trusted IP
# (Only works if you're running this from inside the Docker network or cluster)
curl -v -H "Remote-User: testuser" http://bindery:8787/api/v1/auth/status

If this returns 200 and "authenticated": true, Bindery's proxy auth is working — the problem is the proxy not forwarding the header.

Authelia: check authResponseHeaders

The Traefik forwardauth middleware must include Remote-User in authResponseHeaders:

# Must be present:
authResponseHeaders: Remote-User,Remote-Groups,Remote-Name,Remote-Email

Verify by checking Traefik's dashboard or static config. If missing, add it and redeploy Traefik.

Authentik: check copy_headers (Caddy) or authResponseHeaders (Traefik)

Caddy forward_auth block must include:

copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email

Traefik forwardauth middleware must include X-Authentik-Username in authResponseHeaders.

nginx: check auth_request_set

auth_request_set $user $upstream_http_remote_user;
proxy_set_header Remote-User $user;

Both lines are required. The auth_request_set captures the header from Authelia's response; proxy_set_header forwards it to Bindery.


Step 4 — Confirm the source IP is trusted

Bindery checks that the request arrives from a trusted proxy IP. If the source IP doesn't match BINDERY_TRUSTED_PROXY, Bindery ignores the identity header and returns 401.

Find the actual source IP

Enable debug logging (Step 2) and look for a line like:

remote addr: 172.20.0.5 — not in trusted proxies [172.20.0.0/24]

The CIDR must cover the IP Bindery sees as the request source — this is the Traefik/Caddy/nginx container IP, not your browser IP.

Docker: find the bridge network CIDR

docker network inspect bridge | jq '.[].IPAM.Config[].Subnet'
# or for a named network:
docker network inspect my_network | jq '.[].IPAM.Config[].Subnet'

Use the subnet (e.g. 172.20.0.0/16) as BINDERY_TRUSTED_PROXY.

Kubernetes: find the pod CIDR

kubectl cluster-info dump | grep -m1 "cluster-cidr"
# or
kubectl get nodes -o jsonpath='{.items[0].spec.podCIDR}'

Use the pod CIDR (e.g. 10.244.0.0/16) as BINDERY_TRUSTED_PROXY.

After updating the env var, restart Bindery and confirm the startup log reflects the new CIDR.


Step 5 — Check the header name matches

BINDERY_PROXY_AUTH_HEADER must exactly match the header name your proxy sets.

Proxy Default header Notes
Authelia Remote-User Set via authResponseHeaders in forwardauth middleware
Authentik (Caddy) X-Authentik-Username Set via copy_headers in forward_auth block
Authentik (Traefik) X-Authentik-Username Set via authResponseHeaders
Custom / Keycloak varies Check your IdP's docs for the forwarded header name

Header names are case-insensitive in HTTP but must match what the proxy actually sends. Use debug logging (Step 2) to see the exact header name as received.


Step 6 — Confirm the login page is in proxy mode

If you see the password form instead of "Sign in via your SSO provider", the UI hasn't picked up the mode change.

curl -s http://bindery:8787/api/v1/auth/status | jq '{mode, authenticated}'

If mode is not "proxy", the setting wasn't saved. Re-apply it (Step 1) and hard-refresh the browser (Ctrl+Shift+R).


Step 7 — OPDS or API scripts returning 401

OPDS clients (KOReader, Moon+ Reader) and automation scripts don't go through the SSO flow. They must use X-Api-Key directly.

Either:

  1. Exempt /opds/* and /api/* from the proxy's authentication middleware (recommended), so those paths reach Bindery unauthenticated and Bindery enforces its own API-key check.
  2. Or pass ?apikey=<key> as a query parameter on OPDS URLs.

See your proxy's docs for path-based authentication exemptions:

  • Authelia: resources field in access-control rules with policy: bypass
  • Authentik: unprotect the /api/ path in the application's policy bindings

Still stuck?

Collect this information before asking for help:

# Bindery version and startup log
docker logs bindery 2>&1 | head -20

# Current auth status
curl -s http://bindery:8787/api/v1/auth/status | jq .

# Trusted proxy env var as seen by Bindery (from startup log)
docker logs bindery 2>&1 | grep "trusted proxies"

Then open an issue at github.com/vavallee/bindery/issues with the above output and your proxy config (redact any secrets).

See also: Troubleshooting — Proxy SSO | docs/auth-proxy.md

Clone this wiki locally