BlueSky custom feed authentication errors usually happen before ranking logic matters. The feed generator service is reachable, but the authenticated getFeedSkeleton request cannot be trusted, verified, or matched to the expected service DID.
The important correction is this: the feed generator does not generate the user's service JWT for the request. The request to the feed generator is authenticated with a JWT signed by the user's repo signing key, and the feed generator verifies that token before deciding how to respond.
Read BlueSky's custom feeds guide for the AppView, feed generator DID, getFeedSkeleton, and service-JWT request flow.
How custom feed authentication works
The custom feed guide explains that the AppView resolves the feed declaration, finds the Feed Generator DID document, sends a getFeedSkeleton request to the declared service endpoint, and authenticates that request with a JWT signed by the user's repo signing key.
The service-auth guide describes the JWT payload shape: iss is the user's DID, aud is the service DID receiving the request, and exp is a short expiration time. The feed generator should verify the signing key and always check audience.
Review BlueSky's service-auth guide before debugging audience, issuer, expiration, or signing-key failures.
Common 401 and proxy auth causes
- The feed generator verifies the JWT against the wrong audience DID.
- The DID document service endpoint does not match the deployed feed host.
- The token is expired because clocks are skewed or the request is replayed too late.
- The feed server treats service auth like an app-password session token.
- The service cannot resolve the user's DID signing key or has a stale DID cache.
- The HTTPS endpoint, path, or port 443 deployment is wrong, so the request reaches the wrong service.
Do not confuse service auth with user login
A BlueSky app password or client-server session is not the same thing as service-to-service auth. Feed generator requests are about proving the requester DID to the feed service. If the server expects a normal app session token, it can reject a valid feed request.
The getFeedSkeleton lexicon also says auth is optional depending on provider requirements and provides the DID of the requester. Public feeds may not need every personalized auth branch, but feed services should still handle the official flow correctly when auth is present.
A practical debugging checklist
- Log the request path, Authorization header presence, feed AT URI, limit, cursor, and request time.
- Resolve the feed generator DID document and confirm the service endpoint points to the current host.
- Verify the JWT audience equals the feed generator service DID.
- Verify issuer, expiration, and signing key resolution.
- Return clear 401 diagnostics in logs, not public error details to users.
- Keep feed ranking, pagination, and timeout checks separate from auth verification.
If authentication is correct but the feed is still slow, use the custom feed timeout troubleshooting guide to isolate response latency, cursor shape, and getFeedSkeleton payload issues.
Where ONYX fits for non-feed developers
Most brands do not need to run a feed generator to be discoverable. They need consistent posts with clear text intent, stable topics, readable threads, and useful timing. That is the publishing side of the problem, and it is where ONYX is focused.
Use custom feeds when your team is actually building a feed service. Use ONYX when your team wants brand posts to be clear enough for native search, custom feeds, lists, starter packs, and human readers to classify naturally.
Build a feed-friendly BlueSky content calendar with ONYX without managing feed server auth lifecycles.