Skip to content

Fix qBittorrent V2 auth check breaking against qBit 5.2.0+ (empty 204 response) - #158

Closed
benhumphry wants to merge 1 commit into
pennydreadful:developfrom
benhumphry:qbit-204-fix
Closed

benhumphry wants to merge 1 commit into
pennydreadful:developfrom
benhumphry:qbit-204-fix

Conversation

@benhumphry

Copy link
Copy Markdown

Problem

qBittorrent 5.2.0 changed POST /api/v2/auth/login to return HTTP 204 No Content with an empty body on successful authentication. Before 5.2.0 the endpoint returned HTTP 200 with body "Ok.".

The auth check in QBittorrentProxyV2.AuthenticateClient is:

// returns "Fails." on bad login
if (response.Content != "Ok.")
{
    _logger.Debug("qbitTorrent authentication failed.");
    throw new DownloadClientAuthenticationException("Failed to authenticate with qBittorrent.");
}

An empty 204 body is not "Ok.", so this throws DownloadClientAuthenticationException against any qBittorrent 5.2.0+ even when the login actually succeeded. The download client shows as "Failed to authenticate with qBittorrent" in Bookshelf and stops working.

The change is observable directly:

$ curl -i -X POST -d 'username=admin&password=...' http://qbit:8080/api/v2/auth/login
HTTP/1.1 204 No Content
Set-Cookie: SID=...; HttpOnly; SameSite=Strict

(Pre-5.2.0 the same call returned HTTP/1.1 200 OK and body Ok..)

The qBit 5.2.0 release-notes line that documents this is WEBAPI: Send 204 when WebAPI response contains no data (qbittorrent/qBittorrent#21472, shipped in 5.2.0).

Fix

Add a IsNotNullOrWhiteSpace() guard so an empty body short-circuits the failure branch — only treat the response as failed if it has content AND that content is not "Ok.":

// returns "Fails." on bad login; qBit 5.2.0+ returns empty 204 on success
if (response.Content.IsNotNullOrWhiteSpace() && response.Content != "Ok.")
{
    _logger.Debug("qbitTorrent authentication failed.");
    throw new DownloadClientAuthenticationException("Failed to authenticate with qBittorrent.");
}

IsNotNullOrWhiteSpace() is already in scope via the existing using NzbDrone.Common.Extensions; import — no new dependencies.

Why this is the right shape

The same one-line guard already lives in all the other Servarr forks that share the qBit V2 proxy:

Project Status File
Sonarr Has the guard QBittorrentProxyV2.cs
Radarr Has the guard (mirror of Sonarr)
Lidarr Has the guard (mirror of Sonarr)
Bookshelf Missing the guard — this PR —

The behaviour difference is exactly why Sonarr/Radarr/Lidarr keep working against qBit 5.2.0 while Bookshelf does not. This change brings Bookshelf into line.

Risk

Negligible. The guard only changes behaviour when response.Content is null or whitespace, which previously was always classified as "auth failed" and now is classified as "auth ok". Real failures still return either a non-2xx HTTP status (handled by the catch (HttpException) block above) or body "Fails." (still caught by the != "Ok." half of the new condition).

Test plan

  • Connect Bookshelf to qBittorrent 5.1.x (200 + "Ok."): auth still succeeds. ✅
  • Connect Bookshelf to qBittorrent 5.2.0+ (204 + empty body): auth now succeeds. ✅ (was failing pre-patch)
  • Connect Bookshelf with wrong password to either qBit version (200 + "Fails."): auth still throws DownloadClientAuthenticationException. ✅

Verified locally by rebuilding Readarr.Core.dll from a patched develop checkout (commit c21c4134…) and dropping it into the upstream ghcr.io/pennydreadful/bookshelf:hardcover image. Test Connection in Settings → Download Clients flips from red to green.

… response)

qBittorrent 5.2.0 changed POST /api/v2/auth/login to return HTTP 204
with an empty body on successful authentication. Pre-5.2.0 the endpoint
returned HTTP 200 with body "Ok.".

The auth check in QBittorrentProxyV2.AuthenticateClient compares
response.Content against the literal "Ok." with no null/whitespace
guard, so an empty 204 body trips the failure branch and throws
DownloadClientAuthenticationException against any qBit 5.2.0+ even when
authentication actually succeeded.

Add a IsNotNullOrWhiteSpace() guard so the check only treats the
response as failed when the body is non-empty AND not "Ok.". This
matches the equivalent guard already in Sonarr/Radarr/Lidarr's qBit V2
proxy.

IsNotNullOrWhiteSpace() is already in scope via NzbDrone.Common.Extensions
(existing using directive at the top of the file).
@AlvaroEstradaDev

Copy link
Copy Markdown

I made a local build with this fix for myself, I can verify that it works.

@Florentina72

Copy link
Copy Markdown

I request that the creators of Bookshelf fix this within Bookshelf itself. The above kind of solutions are Greek and Latin for us commoners.

@GinSoakedBoy

Copy link
Copy Markdown

I request that the creators of Bookshelf fix this within Bookshelf itself. The above kind of solutions are Greek and Latin for us commoners.

+1 for this. I see this thread referenced as a 'fixed' issue, but I don't see a fix.

@EggEnormous

Copy link
Copy Markdown

I would also dearly love for this to be incorporated into Bookshelf.

@ozhound

ozhound commented May 30, 2026

Copy link
Copy Markdown

Also confirming this PR works and i can connect to qbit now.

@ReaVNaiL

Copy link
Copy Markdown

We'll need to wait for one of the maintainers to merge it unfortunately. The fix works.

@Adiar1

Adiar1 commented May 31, 2026

Copy link
Copy Markdown

I'm waiting for it as well. Just dropping a comment to show demand

@manalshaikh

Copy link
Copy Markdown

any update? without this, its completely borked and wouldn't work. im setting up a new instance of bookshelf(for the first time ever) and cant seem to get it to work. this is kinda breaking.

@SolomonIxanSmith

Copy link
Copy Markdown

Also commenting to try and show demand.

@Roskott

Roskott commented Jun 3, 2026

Copy link
Copy Markdown

Also bumping to show desire

@Brodieman

Brodieman commented Jun 3, 2026 •

Copy link
Copy Markdown

Just trying to add Bookshelf as an app and running into this. I do not see a word on an official fix. Anyone have step by step on fixing this manually? The code to fix it on top, I see that, but I do not see a file or where to put it. If someone has something or could write up something people could follow to correct this until Bookshelf does, we would apricate it.

@EFH52

EFH52 commented Jun 4, 2026

Copy link
Copy Markdown

Curious as to whether there is life here or that we count things a dead and move on to other projects. I spent a couple hours working this issue yesterday before finding this issue and the attendant PR.

@GinSoakedBoy

Copy link
Copy Markdown

Are there any other forks of Readarr out there?

Chaptarr is still in alpha, but the public beta should be coming soon.

@Brodieman

Copy link
Copy Markdown

If this is never fixed, I get it. These projects are a lot of time. I am just hoping someone can write something up for people to follow along to correct this.

I think most of us that use stuff like think are not programmers but have good IT knowledge to follow along. Programmers can figure this out, people with IT knowledge might not be able to.

@SolomonIxanSmith

Copy link
Copy Markdown

If this is never fixed, I get it. These projects are a lot of time. I am just hoping someone can write something up for people to follow along to correct this.

I think most of us that use stuff like think are not programmers but have good IT knowledge to follow along. Programmers can figure this out, people with IT knowledge might not be able to.

What I did, and others probably have done, is fork the project and merge the pull request and then point docker to your image. It doesn't require any coding or anything other than using the github website. I'd recommend asking your AI tool of choice to help you with the steps.

@EggEnormous

EggEnormous commented Jun 4, 2026 via email

Copy link
Copy Markdown

@Brodieman

Copy link
Copy Markdown

If this is never fixed, I get it. These projects are a lot of time. I am just hoping someone can write something up for people to follow along to correct this.
I think most of us that use stuff like think are not programmers but have good IT knowledge to follow along. Programmers can figure this out, people with IT knowledge might not be able to.

What I did, and others probably have done, is fork the project and merge the pull request and then point docker to your image. It doesn't require any coding or anything other than using the github website. I'd recommend asking your AI tool of choice to help you with the steps.

I use TrueNAS, not a standard Docker image, so that would not work for me.. However, I have been in IT for 20 years but never in coding. When you talk about forking and stuff, I have no clue what that means or how to accomplish it. I was hoping for a "this file is located here, change this code to this". That I can do. Thanks for the reply

@benhumphry
benhumphry requested a review from ReaVNaiL June 11, 2026 15:10
@AlvaroEstradaDev

Copy link
Copy Markdown

I made a fork and a build of this fix, everyone is free to use it until an official update is done.
The only change I did was for the CI to be able to build it, but I invite everyone to check the code before installing.
ghcr.io/alvaroestradadev/bookshelf:hardcover

@EggEnormous

Copy link
Copy Markdown

I made a fork and a build of this fix, everyone is free to use it until an official update is done. The only change I did was for the CI to be able to build it, but I invite everyone to check the code before installing. ghcr.io/alvaroestradadev/bookshelf:hardcover

You're my hero!

@Adiar1

Adiar1 commented Jun 21, 2026

Copy link
Copy Markdown

I made a fork and a build of this fix, everyone is free to use it until an official update is done. The only change I did was for the CI to be able to build it, but I invite everyone to check the code before installing. ghcr.io/alvaroestradadev/bookshelf:hardcover

Yeah that's what I ended up doing too.

@GinSoakedBoy

Copy link
Copy Markdown

I made a fork and a build of this fix, everyone is free to use it until an official update is done. The only change I did was for the CI to be able to build it, but I invite everyone to check the code before installing. ghcr.io/alvaroestradadev/bookshelf:hardcover

Would you be willing to apply the fix to the softcover (Goodreads) version of Readarr?

@AlvaroEstradaDev

Copy link
Copy Markdown

I made a fork and a build of this fix, everyone is free to use it until an official update is done. The only change I did was for the CI to be able to build it, but I invite everyone to check the code before installing. ghcr.io/alvaroestradadev/bookshelf:hardcover

Would you be willing to apply the fix to the softcover (Goodreads) version of Readarr?

It got build at the same time, sorry if that wasn't clear.
ghcr.io/alvaroestradadev/bookshelf:softcover

@GinSoakedBoy

Copy link
Copy Markdown

I made a fork and a build of this fix, everyone is free to use it until an official update is done. The only change I did was for the CI to be able to build it, but I invite everyone to check the code before installing. ghcr.io/alvaroestradadev/bookshelf:hardcover

Would you be willing to apply the fix to the softcover (Goodreads) version of Readarr?

It got build at the same time, sorry if that wasn't clear. ghcr.io/alvaroestradadev/bookshelf:softcover

Derp, thank you!

@andrewmuhn andrewmuhn left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@Roskott

Roskott commented Jul 8, 2026

Copy link
Copy Markdown

So, what's preventing the build for this? I see @ReaVNaiL approved, but we're waiting for... @ReaVNaiL to approve? is it just a double tap issue?

@klein1jo

Copy link
Copy Markdown

@Roskott penny would have to merge and penny has gone MIA. I've created a fork that merges all of bookshelf's open pull requests including a fix for Qbittorrent 5.2.x. You can use it if you want. https://github.com/klein1jo/bookshelf

@Kazwahs

Kazwahs commented Jul 16, 2026

Copy link
Copy Markdown

On Truenas Scale I converted Bookshelf to a custom app and changed the image to the hardcover one from @klein1jo, https://github.com/klein1jo/bookshelf. Worked great, back up and running with Qbit.

3n8 pushed a commit to 3n8/bookshelf that referenced this pull request Aug 27, 2026
qBittorrent 5.2.0+ returns 204 No Content on successful /api/v2/auth/login
instead of 200 with body "Ok.". Treat empty bodies as success and map HTTP
401 to an authentication error, matching Sonarr/Radarr.

Also publish images as ghcr.io/3n8/bookshelf and grant the CI token the
permissions a fork needs to push packages.

Fixes pennydreadful#160, pennydreadful#165, pennydreadful#178 (unmerged upstream PRs pennydreadful#158, pennydreadful#162, pennydreadful#170).
@joel35

joel35 commented Sep 10, 2026

Copy link
Copy Markdown

Waiting for this fix. Any update? Seems like it should be good-to-go.

@pennydreadful

Copy link
Copy Markdown
Owner

sorry i use an older qbit so don't have this problem

fixed in #170

if you'd like to help contribute i would be glad to add maintainers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.