[Bug]: Patreon RSS Feed bouncing on useragent fail #3093

Closed
opened 2026-04-25 00:13:37 +02:00 by adam · 15 comments
Owner

Originally created by @noticons on GitHub (Nov 14, 2025).

What happened?

RSS feeds from patreon were formerly working just fine, and still work in other apps on my network, but Audiobookshelf has recently been unable to download episodes automatically or on request when I "check for episodes" through the webUI.

What did you expect to happen?

Downloading episodes! lol

Steps to reproduce the issue

If you don't have a patreon rss feed and don't want to pay to find out whether its working or not, Linux User Space has a free tier that has an RSS feed you can try out. https://www.patreon.com/linuxuserspace
Once you add the "member's only" RSS feed to audiobookshelf, everything works fine, including metadata and coverart, but fails to download episodes. I have included the log, which is below.

Audiobookshelf version

2.30.0

How are you running audiobookshelf?

Docker

What OS is your Audiobookshelf server hosted from?

Linux

If the issue is being seen in the UI, what browsers are you seeing the problem on?

None

Logs

[ffmpegHelpers] All User-Agent attempts failed for url "https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D" [AxiosError: Request failed with status code 403] { code: 'ERR_BAD_REQUEST', config: { transitional: { silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false }, adapter: [Function: httpAdapter], transformRequest: [ [Function: transformRequest] ], transformResponse: [ [Function: transformResponse] ], timeout: 30000, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: { FormData: [Function] }, validateStatus: [Function: validateStatus], headers: { Accept: '*/*', 'User-Agent': 'audiobookshelf (+https://audiobookshelf.org)' }, url: 'https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', method: 'get', responseType: 'stream', data: undefined }, request: <ref *1> ClientRequest { _events: [Object: null prototype] { abort: [Function (anonymous)], aborted: [Function (anonymous)], connect: [Function (anonymous)], error: [Function (anonymous)], socket: [Function (anonymous)], timeout: [Function (anonymous)], finish: [Function: requestOnFinish] }, _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: false, _last: true, chunkedEncoding: false, shouldKeepAlive: true, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: false, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, strictContentLength: false, _contentLength: 0, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: false, socket: TLSSocket { _tlsOptions: [Object], _secureEstablished: true, _securePending: false, _newSessionPending: false, _controlReleased: true, secureConnecting: false, _SNICallback: null, servername: 'www.patreon.com', alpnProtocol: false, authorized: true, authorizationError: null, encrypted: true, _events: [Object: null prototype], _eventsCount: 9, connecting: false, _hadError: false, _parent: null, _host: 'www.patreon.com', _closeAfterHandlingError: false, _readableState: [ReadableState], _writableState: [WritableState], allowHalfOpen: false, _maxListeners: undefined, _sockname: null, _pendingData: null, _pendingEncoding: '', server: undefined, _server: null, ssl: [TLSWrap], _requestCert: true, _rejectUnauthorized: true, timeout: 30000, parser: null, _httpMessage: [Circular *1], autoSelectFamilyAttemptedAddresses: [Array], [Symbol(alpncallback)]: null, [Symbol(res)]: [TLSWrap], [Symbol(verified)]: true, [Symbol(pendingSession)]: null, [Symbol(async_id_symbol)]: 153906, [Symbol(kHandle)]: [TLSWrap], [Symbol(lastWriteQueueSize)]: 0, [Symbol(timeout)]: Timeout { _idleTimeout: 30000, _idlePrev: [TimersList], _idleNext: [Timeout], _idleStart: 13910870, _onTimeout: [Function: bound ], _timerArgs: undefined, _repeat: null, _destroyed: false, [Symbol(refed)]: false, [Symbol(kHasPrimitive)]: false, [Symbol(asyncId)]: 153915, [Symbol(triggerId)]: 153910 }, [Symbol(kBuffer)]: null, [Symbol(kBufferCb)]: null, [Symbol(kBufferGen)]: null, [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false, [Symbol(kSetNoDelay)]: false, [Symbol(kSetKeepAlive)]: true, [Symbol(kSetKeepAliveInitialDelay)]: 60, [Symbol(kBytesRead)]: 0, [Symbol(kBytesWritten)]: 0, [Symbol(connect-options)]: [Object] }, _header: 'GET /api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D HTTP/1.1\r\n' + 'Accept: */*\r\n' + 'User-Agent: audiobookshelf (+https://audiobookshelf.org)\r\n' + 'Host: www.patreon.com\r\n' + 'Connection: keep-alive\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: Agent { _events: [Object: null prototype], _eventsCount: 2, _maxListeners: undefined, defaultPort: 443, protocol: 'https:', options: [Object: null prototype], requests: [Object: null prototype] {}, sockets: [Object: null prototype], freeSockets: [Object: null prototype] {}, keepAliveMsecs: 1000, keepAlive: true, maxSockets: Infinity, maxFreeSockets: 256, scheduling: 'lifo', maxTotalSockets: Infinity, totalSocketCount: 2, maxCachedSessions: 100, _sessionCache: [Object], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false }, socketPath: undefined, method: 'GET', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', _ended: false, res: IncomingMessage { _events: [Object], _readableState: [ReadableState], _maxListeners: undefined, socket: [TLSSocket], httpVersionMajor: 1, httpVersionMinor: 1, httpVersion: '1.1', complete: true, rawHeaders: [Array], rawTrailers: [], joinDuplicateHeaders: undefined, aborted: false, upgrade: false, url: '', method: null, statusCode: 403, statusMessage: 'Forbidden', client: [TLSSocket], _consuming: false, _dumped: false, req: [Circular *1], _eventsCount: 1, responseUrl: 'https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', redirects: [], [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false, [Symbol(kHeaders)]: [Object], [Symbol(kHeadersCount)]: 22, [Symbol(kTrailers)]: null, [Symbol(kTrailersCount)]: 0 }, aborted: false, timeoutCb: [Function: emitRequestTimeout], upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'www.patreon.com', protocol: 'https:', _redirectable: Writable { _events: [Object], _writableState: [WritableState], _maxListeners: undefined, _options: [Object], _ended: true, _ending: true, _redirectCount: 0, _redirects: [], _requestBodyLength: 0, _requestBodyBuffers: [], _eventsCount: 3, _onNativeResponse: [Function (anonymous)], _currentRequest: [Circular *1], _currentUrl: 'https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', _timeout: null, [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false }, [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(kBytesWritten)]: 0, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kOutHeaders)]: [Object: null prototype] { accept: [Array], 'user-agent': [Array], host: [Array] }, [Symbol(errored)]: null, [Symbol(kHighWaterMark)]: 16384, [Symbol(kRejectNonStandardBodyWrites)]: false, [Symbol(kUniqueHeaders)]: null }, response: { status: 403, statusText: 'Forbidden', headers: { date: 'Fri, 14 Nov 2025 14:00:19 GMT', 'content-type': 'application/json', 'content-length': '2', connection: 'keep-alive', 'set-cookie': [Array], 'report-to': '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=longtunneljibberish"}],"group":"cf-nel","max_age":604800}', nel: '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}', 'strict-transport-security': 'max-age=2592000', 'x-content-type-options': 'nosniff', server: 'cloudflare', 'cf-ray': '99e708d39b6153f7-ATL' }, config: { transitional: [Object], adapter: [Function: httpAdapter], transformRequest: [Array], transformResponse: [Array], timeout: 30000, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: [Object], validateStatus: [Function: validateStatus], headers: [Object], url: 'https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', method: 'get', responseType: 'stream', data: undefined }, request: <ref *1> ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: false, _last: true, chunkedEncoding: false, shouldKeepAlive: true, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: false, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, strictContentLength: false, _contentLength: 0, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: false, socket: [TLSSocket], _header: 'GET /api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D HTTP/1.1\r\n' + 'Accept: */*\r\n' + 'User-Agent: audiobookshelf (+https://audiobookshelf.org)\r\n' + 'Host: www.patreon.com\r\n' + 'Connection: keep-alive\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: [Agent], socketPath: undefined, method: 'GET', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', _ended: false, res: [IncomingMessage], aborted: false, timeoutCb: [Function: emitRequestTimeout], upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'www.patreon.com', protocol: 'https:', _redirectable: [Writable], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(kBytesWritten)]: 0, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kOutHeaders)]: [Object: null prototype], [Symbol(errored)]: null, [Symbol(kHighWaterMark)]: 16384, [Symbol(kRejectNonStandardBodyWrites)]: false, [Symbol(kUniqueHeaders)]: null }, data: IncomingMessage { _events: [Object], _readableState: [ReadableState], _maxListeners: undefined, socket: [TLSSocket], httpVersionMajor: 1, httpVersionMinor: 1, httpVersion: '1.1', complete: true, rawHeaders: [Array], rawTrailers: [], joinDuplicateHeaders: undefined, aborted: false, upgrade: false, url: '', method: null, statusCode: 403, statusMessage: 'Forbidden', client: [TLSSocket], _consuming: false, _dumped: false, req: [ClientRequest], _eventsCount: 1, responseUrl: 'https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', redirects: [], [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false, [Symbol(kHeaders)]: [Object], [Symbol(kHeadersCount)]: 22, [Symbol(kTrailers)]: null, [Symbol(kTrailersCount)]: 0 } } }

Additional Notes

No response

Originally created by @noticons on GitHub (Nov 14, 2025). ### What happened? RSS feeds from patreon were formerly working just fine, and still work in other apps on my network, but Audiobookshelf has recently been unable to download episodes automatically or on request when I "check for episodes" through the webUI. ### What did you expect to happen? Downloading episodes! lol ### Steps to reproduce the issue If you don't have a patreon rss feed and don't want to pay to find out whether its working or not, Linux User Space has a free tier that has an RSS feed you can try out. https://www.patreon.com/linuxuserspace Once you add the "member's only" RSS feed to audiobookshelf, everything works fine, including metadata and coverart, but fails to download episodes. I have included the log, which is below. ### Audiobookshelf version 2.30.0 ### How are you running audiobookshelf? Docker ### What OS is your Audiobookshelf server hosted from? Linux ### If the issue is being seen in the UI, what browsers are you seeing the problem on? None ### Logs ```shell [ffmpegHelpers] All User-Agent attempts failed for url "https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D" [AxiosError: Request failed with status code 403] { code: 'ERR_BAD_REQUEST', config: { transitional: { silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false }, adapter: [Function: httpAdapter], transformRequest: [ [Function: transformRequest] ], transformResponse: [ [Function: transformResponse] ], timeout: 30000, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: { FormData: [Function] }, validateStatus: [Function: validateStatus], headers: { Accept: '*/*', 'User-Agent': 'audiobookshelf (+https://audiobookshelf.org)' }, url: 'https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', method: 'get', responseType: 'stream', data: undefined }, request: <ref *1> ClientRequest { _events: [Object: null prototype] { abort: [Function (anonymous)], aborted: [Function (anonymous)], connect: [Function (anonymous)], error: [Function (anonymous)], socket: [Function (anonymous)], timeout: [Function (anonymous)], finish: [Function: requestOnFinish] }, _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: false, _last: true, chunkedEncoding: false, shouldKeepAlive: true, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: false, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, strictContentLength: false, _contentLength: 0, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: false, socket: TLSSocket { _tlsOptions: [Object], _secureEstablished: true, _securePending: false, _newSessionPending: false, _controlReleased: true, secureConnecting: false, _SNICallback: null, servername: 'www.patreon.com', alpnProtocol: false, authorized: true, authorizationError: null, encrypted: true, _events: [Object: null prototype], _eventsCount: 9, connecting: false, _hadError: false, _parent: null, _host: 'www.patreon.com', _closeAfterHandlingError: false, _readableState: [ReadableState], _writableState: [WritableState], allowHalfOpen: false, _maxListeners: undefined, _sockname: null, _pendingData: null, _pendingEncoding: '', server: undefined, _server: null, ssl: [TLSWrap], _requestCert: true, _rejectUnauthorized: true, timeout: 30000, parser: null, _httpMessage: [Circular *1], autoSelectFamilyAttemptedAddresses: [Array], [Symbol(alpncallback)]: null, [Symbol(res)]: [TLSWrap], [Symbol(verified)]: true, [Symbol(pendingSession)]: null, [Symbol(async_id_symbol)]: 153906, [Symbol(kHandle)]: [TLSWrap], [Symbol(lastWriteQueueSize)]: 0, [Symbol(timeout)]: Timeout { _idleTimeout: 30000, _idlePrev: [TimersList], _idleNext: [Timeout], _idleStart: 13910870, _onTimeout: [Function: bound ], _timerArgs: undefined, _repeat: null, _destroyed: false, [Symbol(refed)]: false, [Symbol(kHasPrimitive)]: false, [Symbol(asyncId)]: 153915, [Symbol(triggerId)]: 153910 }, [Symbol(kBuffer)]: null, [Symbol(kBufferCb)]: null, [Symbol(kBufferGen)]: null, [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false, [Symbol(kSetNoDelay)]: false, [Symbol(kSetKeepAlive)]: true, [Symbol(kSetKeepAliveInitialDelay)]: 60, [Symbol(kBytesRead)]: 0, [Symbol(kBytesWritten)]: 0, [Symbol(connect-options)]: [Object] }, _header: 'GET /api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D HTTP/1.1\r\n' + 'Accept: */*\r\n' + 'User-Agent: audiobookshelf (+https://audiobookshelf.org)\r\n' + 'Host: www.patreon.com\r\n' + 'Connection: keep-alive\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: Agent { _events: [Object: null prototype], _eventsCount: 2, _maxListeners: undefined, defaultPort: 443, protocol: 'https:', options: [Object: null prototype], requests: [Object: null prototype] {}, sockets: [Object: null prototype], freeSockets: [Object: null prototype] {}, keepAliveMsecs: 1000, keepAlive: true, maxSockets: Infinity, maxFreeSockets: 256, scheduling: 'lifo', maxTotalSockets: Infinity, totalSocketCount: 2, maxCachedSessions: 100, _sessionCache: [Object], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false }, socketPath: undefined, method: 'GET', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', _ended: false, res: IncomingMessage { _events: [Object], _readableState: [ReadableState], _maxListeners: undefined, socket: [TLSSocket], httpVersionMajor: 1, httpVersionMinor: 1, httpVersion: '1.1', complete: true, rawHeaders: [Array], rawTrailers: [], joinDuplicateHeaders: undefined, aborted: false, upgrade: false, url: '', method: null, statusCode: 403, statusMessage: 'Forbidden', client: [TLSSocket], _consuming: false, _dumped: false, req: [Circular *1], _eventsCount: 1, responseUrl: 'https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', redirects: [], [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false, [Symbol(kHeaders)]: [Object], [Symbol(kHeadersCount)]: 22, [Symbol(kTrailers)]: null, [Symbol(kTrailersCount)]: 0 }, aborted: false, timeoutCb: [Function: emitRequestTimeout], upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'www.patreon.com', protocol: 'https:', _redirectable: Writable { _events: [Object], _writableState: [WritableState], _maxListeners: undefined, _options: [Object], _ended: true, _ending: true, _redirectCount: 0, _redirects: [], _requestBodyLength: 0, _requestBodyBuffers: [], _eventsCount: 3, _onNativeResponse: [Function (anonymous)], _currentRequest: [Circular *1], _currentUrl: 'https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', _timeout: null, [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false }, [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(kBytesWritten)]: 0, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kOutHeaders)]: [Object: null prototype] { accept: [Array], 'user-agent': [Array], host: [Array] }, [Symbol(errored)]: null, [Symbol(kHighWaterMark)]: 16384, [Symbol(kRejectNonStandardBodyWrites)]: false, [Symbol(kUniqueHeaders)]: null }, response: { status: 403, statusText: 'Forbidden', headers: { date: 'Fri, 14 Nov 2025 14:00:19 GMT', 'content-type': 'application/json', 'content-length': '2', connection: 'keep-alive', 'set-cookie': [Array], 'report-to': '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=longtunneljibberish"}],"group":"cf-nel","max_age":604800}', nel: '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}', 'strict-transport-security': 'max-age=2592000', 'x-content-type-options': 'nosniff', server: 'cloudflare', 'cf-ray': '99e708d39b6153f7-ATL' }, config: { transitional: [Object], adapter: [Function: httpAdapter], transformRequest: [Array], transformResponse: [Array], timeout: 30000, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: [Object], validateStatus: [Function: validateStatus], headers: [Object], url: 'https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', method: 'get', responseType: 'stream', data: undefined }, request: <ref *1> ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: false, _last: true, chunkedEncoding: false, shouldKeepAlive: true, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: false, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, strictContentLength: false, _contentLength: 0, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: false, socket: [TLSSocket], _header: 'GET /api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D HTTP/1.1\r\n' + 'Accept: */*\r\n' + 'User-Agent: audiobookshelf (+https://audiobookshelf.org)\r\n' + 'Host: www.patreon.com\r\n' + 'Connection: keep-alive\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: [Agent], socketPath: undefined, method: 'GET', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', _ended: false, res: [IncomingMessage], aborted: false, timeoutCb: [Function: emitRequestTimeout], upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'www.patreon.com', protocol: 'https:', _redirectable: [Writable], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(kBytesWritten)]: 0, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kOutHeaders)]: [Object: null prototype], [Symbol(errored)]: null, [Symbol(kHighWaterMark)]: 16384, [Symbol(kRejectNonStandardBodyWrites)]: false, [Symbol(kUniqueHeaders)]: null }, data: IncomingMessage { _events: [Object], _readableState: [ReadableState], _maxListeners: undefined, socket: [TLSSocket], httpVersionMajor: 1, httpVersionMinor: 1, httpVersion: '1.1', complete: true, rawHeaders: [Array], rawTrailers: [], joinDuplicateHeaders: undefined, aborted: false, upgrade: false, url: '', method: null, statusCode: 403, statusMessage: 'Forbidden', client: [TLSSocket], _consuming: false, _dumped: false, req: [ClientRequest], _eventsCount: 1, responseUrl: 'https://www.patreon.com/api/rss/u/privatekey/e/143238611?sig=otherstuffmightbekey%3D', redirects: [], [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false, [Symbol(kHeaders)]: [Object], [Symbol(kHeadersCount)]: 22, [Symbol(kTrailers)]: null, [Symbol(kTrailersCount)]: 0 } } } ``` ### Additional Notes _No response_
adam added the bug label 2026-04-25 00:13:37 +02:00
adam closed this issue 2026-04-25 00:13:37 +02:00
Author
Owner

@benn447 commented on GitHub (Nov 20, 2025):

I am experiencing a similar issue, but this appears to be a block by patreons cloudflare configuration, or cloudflare has recently updated their WAF rules, maybe causing audiobookshelf to be detected as a bot.

Cloudflare did apparently update their WAF this week, which caused a major outage, maybe this is related? 🤔

@benn447 commented on GitHub (Nov 20, 2025): I am experiencing a similar issue, but this appears to be a block by patreons cloudflare configuration, or cloudflare has recently updated their WAF rules, maybe causing audiobookshelf to be detected as a bot. Cloudflare did apparently update their WAF this week, which caused a major outage, maybe this is related? 🤔
Author
Owner

@noticons commented on GitHub (Nov 21, 2025):

If that is the factor it began two weeks ago--roughly one week before the outage. Whatever the problem is, and I'm sure you're probably right about it being cloudflare, I hope it is able to be resolved in some way.

@noticons commented on GitHub (Nov 21, 2025): If that is the factor it began two weeks ago--roughly one week before the outage. Whatever the problem is, and I'm sure you're probably right about it being cloudflare, I hope it is able to be resolved in some way.
Author
Owner

@noticons commented on GitHub (Nov 21, 2025):

@benn447 are you still experiencing this as of today? I did some checking, and I'm still experiencing the same issue.

@noticons commented on GitHub (Nov 21, 2025): @benn447 are you still experiencing this as of today? I did some checking, and I'm still experiencing the same issue.
Author
Owner

@MikaSturm commented on GitHub (Nov 22, 2025):

I have the same problem with both of my Patreon subscriptions

@MikaSturm commented on GitHub (Nov 22, 2025): I have the same problem with both of my Patreon subscriptions
Author
Owner

@noticons commented on GitHub (Nov 25, 2025):

@MikaSturm If this really is an useragent issue, as it seems to be, it seems the only solution would be a backend change on the server? I'm unfamiliar with this territory.

@noticons commented on GitHub (Nov 25, 2025): @MikaSturm If this really is an useragent issue, as it seems to be, it seems the only solution would be a backend change on the server? I'm unfamiliar with this territory.
Author
Owner

@benn447 commented on GitHub (Nov 25, 2025):

Unfortuneately, this is still occuring.
I suspect that the useragent has been detected as a bot on the cloudflare WAF or patreon has actively flagged it as traffic to be blocked.

I mainly think this is an auto detection on cloudflare, as it is unlikely patreon would actively block paying customers from using specific apps, having said that I recently noticed they are trying to push users to specific platforms like spotify.

I believe that modifing the useragent is probably the easiest solution, however its a bit disengenous to just set the useragent to chrome, firefox etc.

Maybe the better option here is to set a default useragent similar to the existing one, then allow users to modify their useragent if required?

This would mean the user isn't forced to use an incorrect useragent, but can use one if issues like this arrise.

@benn447 commented on GitHub (Nov 25, 2025): Unfortuneately, this is still occuring. I suspect that the useragent has been detected as a bot on the cloudflare WAF or patreon has actively flagged it as traffic to be blocked. I mainly think this is an auto detection on cloudflare, as it is unlikely patreon would actively block paying customers from using specific apps, having said that I recently noticed they are trying to push users to specific platforms like spotify. I believe that modifing the useragent is probably the easiest solution, however its a bit disengenous to just set the useragent to chrome, firefox etc. Maybe the better option here is to set a default useragent similar to the existing one, then allow users to modify their useragent if required? This would mean the user isn't forced to use an incorrect useragent, but can use one if issues like this arrise.
Author
Owner

@Vito0912 commented on GitHub (Nov 26, 2025):

It works completely fine for me. Maybe it's because you downloaded too many episodes, and Patreon protects its service by limiting how many episodes you can download (to prevent redistribution).

So this is not an issue with user agents (the error message appears because it tries multiple and none succeed) - but it does not actually mean it is caused by user-agents.
If a service decides to block users or IPs, in my opinion, it's their right to do so.

So maybe you, @advplyr can take a look, but imho this can be closed and is not an per se issue with user-agents nor ABS and just the service deciding to block users, where ABS can't do anything about it.

I just downloaded all episodes of the above mentioned podcast with no issues. You can try getting a new IP, if it maybe is caused by this. If you are using a VPN, make sure you disconnect (I was prompted by CF when using a VPN)

@Vito0912 commented on GitHub (Nov 26, 2025): It works completely fine for me. Maybe it's because you downloaded too many episodes, and Patreon protects its service by limiting how many episodes you can download (to prevent redistribution). So this is not an issue with user agents (the error message appears because it tries multiple and none succeed) - but it does not actually mean it is caused by user-agents. If a service decides to block users or IPs, in my opinion, it's their right to do so. So maybe you, @advplyr can take a look, but imho this can be closed and is not an per se issue with user-agents nor ABS and just the service deciding to block users, where ABS can't do anything about it. I just downloaded all episodes of the above mentioned podcast with no issues. You can try getting a new IP, if it maybe is caused by this. If you are using a VPN, make sure you disconnect (I was prompted by CF when using a VPN)
Author
Owner

@nichwall commented on GitHub (Nov 26, 2025):

There are a number of user agent related issues and PRs, such as https://github.com/advplyr/audiobookshelf/issues/4758, https://github.com/advplyr/audiobookshelf/issues/3359, and https://github.com/advplyr/audiobookshelf/issues/3322. The initial PR with more discussion is in https://github.com/advplyr/audiobookshelf/pull/3099.

I don't think we necessarily need to expose the user agent string as a setting, because as mentioned in other discussions the point of the user agent is to identify what is being used. But, I can also see the argument for exposing the user agent as a setting.

@nichwall commented on GitHub (Nov 26, 2025): There are a number of user agent related issues and PRs, such as https://github.com/advplyr/audiobookshelf/issues/4758, https://github.com/advplyr/audiobookshelf/issues/3359, and https://github.com/advplyr/audiobookshelf/issues/3322. The initial PR with more discussion is in https://github.com/advplyr/audiobookshelf/pull/3099. I don't think we necessarily need to expose the user agent string as a setting, because as mentioned in other discussions the point of the user agent is to identify what is being used. But, I can also see the argument for exposing the user agent as a setting.
Author
Owner

@MikaSturm commented on GitHub (Nov 26, 2025):

I can confirm for my case, that it's not connected to the user agent, but the IP address of the server I host audiobookshelf on - thanks for the feedback

@MikaSturm commented on GitHub (Nov 26, 2025): I can confirm for my case, that it's not connected to the user agent, but the IP address of the server I host audiobookshelf on - thanks for the feedback
Author
Owner

@Truth-And-Reason commented on GitHub (Nov 29, 2025):

Suggestion : Leave the user agent default as is , but in the podcast details section below "RSS Feed URL" add an input box for a user supplied alternative for that specific podcast. This would allow users a work around and also provide a trouble-shooting tool for users. It may cut down on the amount of help requests and bug reports.

@Truth-And-Reason commented on GitHub (Nov 29, 2025): Suggestion : Leave the user agent default as is , but in the podcast details section below "RSS Feed URL" add an input box for a user supplied alternative for that specific podcast. This would allow users a work around and also provide a trouble-shooting tool for users. It may cut down on the amount of help requests and bug reports.
Author
Owner

@noticons commented on GitHub (Dec 2, 2025):

This may be a simple problem that the private rss is being over-polled and cloudflare is blocking it. So, perhaps reducing from the automatic "every hour" in the automation when adding the feed to a once a day or so will be more helpful. I've set mine this way; I'll report back whether this has been helpful.

@noticons commented on GitHub (Dec 2, 2025): This may be a simple problem that the private rss is being over-polled and cloudflare is blocking it. So, perhaps reducing from the automatic "every hour" in the automation when adding the feed to a once a day or so will be more helpful. I've set mine this way; I'll report back whether this has been helpful.
Author
Owner

@noticons commented on GitHub (Dec 2, 2025):

I also modified my docker-compose file to set the TZ variable for proper time reporting so that my crons will run at the right time in the container, as such:

    environment:
      - TZ=America/New_York
@noticons commented on GitHub (Dec 2, 2025): I also modified my docker-compose file to set the TZ variable for proper time reporting so that my crons will run at the right time in the container, as such: ``` environment: - TZ=America/New_York ```
Author
Owner

@advplyr commented on GitHub (Dec 2, 2025):

I've not seen Patreon have issues with the user agent before. The episode downloader is set up to try 2 different user agent strings.

['audiobookshelf (+https://audiobookshelf.org; like iTMS)', 'audiobookshelf (+https://audiobookshelf.org)']

So far these 2 have worked for all feeds that I'm aware of. If we need to add another one that is easy enough.
I'd prefer not opening this up as another setting if we can avoid it.
I've had 2 private Patreon RSS feeds polling every hour for several years now.

@advplyr commented on GitHub (Dec 2, 2025): I've not seen Patreon have issues with the user agent before. The episode downloader is set up to try 2 different user agent strings. ```js ['audiobookshelf (+https://audiobookshelf.org; like iTMS)', 'audiobookshelf (+https://audiobookshelf.org)'] ``` So far these 2 have worked for all feeds that I'm aware of. If we need to add another one that is easy enough. I'd prefer not opening this up as another setting if we can avoid it. I've had 2 private Patreon RSS feeds polling every hour for several years now.
Author
Owner

@benn447 commented on GitHub (Dec 2, 2025):

This issue might be resolved now, at least for myself.

I tested patreon downloads again yesterday and they were successful.

No cloudflare errors in the logs.

I made no changes and my Ip accessing patreon remains the same.

I still think this was a cloudflare waf issue.
But I only have one patreon feed, so I dont think was cloudflare / patreon rate limiting me based on a large number of requests.

@benn447 commented on GitHub (Dec 2, 2025): This issue might be resolved now, at least for myself. I tested patreon downloads again yesterday and they were successful. No cloudflare errors in the logs. I made no changes and my Ip accessing patreon remains the same. I still think this was a cloudflare waf issue. But I only have one patreon feed, so I dont think was cloudflare / patreon rate limiting me based on a large number of requests.
Author
Owner

@noticons commented on GitHub (Dec 3, 2025):

While there have been a lot of comments about adding useragent options, that has never been the intention of this thread as I opened it. My purpose was to troubleshoot the actual problem that I was having. So there was no "plan" that needed to be disallowed in closing this issue.
In the interest of helping someone else who was experiencing the same issue that I was, the cron and TZ settings that I tried worked perfectly. If someone else experiences difficulty downloading private RSS feeds from Patreon, having it set to something less than every hour may be helpful.
For myself, I have it run once a day in the early morning, in the scheduling option on the audiobookshelf server for the feed. However, in order to have it do this correctly, I had to set the docker container to the correct TZ, as detailed above.

@noticons commented on GitHub (Dec 3, 2025): While there have been a lot of comments about adding useragent options, that has never been the intention of this thread as I opened it. My purpose was to troubleshoot the actual problem that I was having. So there was no "plan" that needed to be disallowed in closing this issue. In the interest of helping someone else who was experiencing the same issue that I was, the cron and TZ settings that I tried worked perfectly. If someone else experiences difficulty downloading private RSS feeds from Patreon, having it set to something less than every hour may be helpful. For myself, I have it run once a day in the early morning, in the scheduling option on the audiobookshelf server for the feed. However, in order to have it do this correctly, I had to set the docker container to the correct TZ, as detailed above.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#3093