Hi,
first off, thank you a LOT for your work on this. It's fantastic!
So, for the past... at least four days, I've been getting consistent 403 errors whenever I tried to update or download anything from AO3 via the plugin. Doesn't matter if the story is adult, locked, or publicly accessible, or even whether it's an update or an entirely new download that's not in my library yet.
I've been on version 4.50.0 for the most of that. Installed 4.50.5 just now and am still seeing the same response. The funny thing is, I installed the CLI via pip, and that has been just fine (at least downloading fresh, since I don't think that integrates with Calibre?) with one of the story URLs from AO3. Which is telling me it's version 4.50.0, btw. I copied the personal.ini from Calibre to test the CLI, so I know that part is all the same.
I've also run Calibre in debug mode, will drop the stack trace from that down here along with the salient bits from my personal.ini. Any help or advice you could provide would be great!
personal.ini:
Code:
[defaults]
is_adult:true
[epub]
include_images:true
make_firstimage_cover:false
[archiveofourown.org]
always_login:true
username:XXXXXXXX
password:XXXXXXXX
collect_series:true
debug log (just for privacy's sake, I've edited my home folder out of the stack trace, replaced with $HOME):
Code:
FFF: DEBUG: 2025-11-03 10:18:14,677: configurable.py(643): config site:test1.com
FFF: DEBUG: 2025-11-03 10:18:23,366: calibre_plugins.fanficfare_plugin.fff_plugin(1163): FanFicFare v4.50.0
FFF: DEBUG: 2025-11-03 10:18:23,469: configurable.py(643): config site:archiveofourown.org
FFF: DEBUG: 2025-11-03 10:18:23,484: configurable.py(1110): use_browser_cache:False
FFF: DEBUG: 2025-11-03 10:18:23,485: configurable.py(1131): use_basic_cache:False
FFF: INFO: 2025-11-03 10:18:23,485: base_otw_adapter.py(193): url: https://archiveofourown.org/works/71694856/navigate?view_adult=true
FFF: INFO: 2025-11-03 10:18:23,485: base_otw_adapter.py(194): metaurl: https://archiveofourown.org/works/71694856?view_adult=true
FFF: DEBUG: 2025-11-03 10:18:23,486: fetcher_requests.py(114):
---------- REQ (GET) RequestsFetcher
https://archiveofourown.org/works/71694856/navigate?view_adult=true
FFF: DEBUG: 2025-11-03 10:18:23,588: fetcher_requests.py(127): response code:403
FFF: ERROR: 2025-11-03 10:18:23,589: calibre_plugins.fanficfare_plugin.dialogs(791): Exception: {'title': 'Ionic Bonds', 'author_sort': 'Tales_of_Reqine', 'author': ['Tales_of_Reqine'], 'comments': '', 'good': False, 'status': 'Error', 'showerror': True, 'calibre_id': 693, 'begin': None, 'end': None, 'comment': "HTTP Error in FFF '403 Client Error: Forbidden for url: https://archiveofourown.org/works/71694856/navigate?view_adult=true'(403)", 'url': 'https://archiveofourown.org/works/71694856', 'site': 'archiveofourown.org', 'series': '', 'added': False, 'pubdate': None, 'publisher': 'archiveofourown.org', 'listorder': 0, 'collision': 'Update EPUB if New Chapters'}:HTTP Error in FFF '403 Client Error: Forbidden for url: https://archiveofourown.org/works/71694856/navigate?view_adult=true'(403)
Traceback (most recent call last):
File "$HOME/.config/calibre/plugins/FanFicFare.zip/fanficfare/fetchers/fetcher_requests.py", line 128, in request
resp.raise_for_status() # raises RequestsHTTPError if error code.
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/requests/models.py", line 1021, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://archiveofourown.org/works/71694856/navigate?view_adult=true
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "calibre_plugins.fanficfare_plugin.dialogs", line 778, in do_loop
self.foreach_function(book)
File "calibre_plugins.fanficfare_plugin.fff_plugin", line 1376, in prep_download_loop
story = self.get_story_metadata_only(adapter)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "calibre_plugins.fanficfare_plugin.fff_plugin", line 1249, in get_story_metadata_only
adapter.getStoryMetadataOnly(get_cover=False)
File "$HOME/.config/calibre/plugins/FanFicFare.zip/fanficfare/adapters/base_adapter.py", line 368, in getStoryMetadataOnly
self.doExtractChapterUrlsAndMetadata(get_cover=get_cover)
File "$HOME/.config/calibre/plugins/FanFicFare.zip/fanficfare/adapters/base_adapter.py", line 472, in doExtractChapterUrlsAndMetadata
return self.extractChapterUrlsAndMetadata()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "$HOME/.config/calibre/plugins/FanFicFare.zip/fanficfare/adapters/base_otw_adapter.py", line 196, in extractChapterUrlsAndMetadata
data = self.get_request(url)
^^^^^^^^^^^^^^^^^^^^^
File "$HOME/.config/calibre/plugins/FanFicFare.zip/fanficfare/requestable.py", line 122, in get_request
return self.get_request_redirected(self.mod_url_request(url),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "$HOME/.config/calibre/plugins/FanFicFare.zip/fanficfare/requestable.py", line 114, in get_request_redirected
(data,rurl) = self.configuration.get_fetcher().get_request_redirected(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "$HOME/.config/calibre/plugins/FanFicFare.zip/fanficfare/fetchers/base_fetcher.py", line 137, in get_request_redirected
fetchresp = self.do_request('GET',
^^^^^^^^^^^^^^^^^^^^^^
File "$HOME/.config/calibre/plugins/FanFicFare.zip/fanficfare/fetchers/decorators.py", line 107, in fetcher_do_request
fetchresp = chainfn(
^^^^^^^^
File "$HOME/.config/calibre/plugins/FanFicFare.zip/fanficfare/fetchers/base_fetcher.py", line 109, in do_request
fetchresp = self.request(method,url,
^^^^^^^^^^^^^^^^^^^^^^^^
File "$HOME/.config/calibre/plugins/FanFicFare.zip/fanficfare/fetchers/fetcher_requests.py", line 149, in request
raise exceptions.HTTPErrorFFF(
fanficfare.exceptions.HTTPErrorFFF: HTTP Error in FFF '403 Client Error: Forbidden for url: https://archiveofourown.org/works/71694856/navigate?view_adult=true'(403)
From all of that, it kind of looks like the plugin might be failing to log in at all, or to be falsely assuming I am logged in if something around the login detection changed recently?
Also, just for the heck of it, I tried to downgrade to calibre plugin 4.49.0, but got the same 403.
For comparison, here's the debug output using the FFF CLI version 4.50.0:
Code:
FFF: DEBUG: 2025-11-03 10:43:46,368: cli.py(230): OS Version:Linux-6.8.0-86-generic-x86_64-with-glibc2.39
FFF: DEBUG: 2025-11-03 10:43:46,368: cli.py(231): Python Version:3.14.0 (main, Oct 7 2025, 09:34:52) [GCC 12.3.0]
FFF: DEBUG: 2025-11-03 10:43:46,368: cli.py(232): FFF Version:4.50.0
FFF: DEBUG: 2025-11-03 10:43:46,368: configurable.py(643): config site:archiveofourown.org
FFF: DEBUG: 2025-11-03 10:43:46,396: configurable.py(1110): use_browser_cache:
FFF: DEBUG: 2025-11-03 10:43:46,396: configurable.py(1131): use_basic_cache:true
You have include_images enabled, but PIL/Pillow (Python Image Library) isn't found.
Images will be included full size in original format.
Continue? (y/n)?
y
FFF: INFO: 2025-11-03 10:43:52,600: base_otw_adapter.py(193): url: https://archiveofourown.org/works/71694856/navigate?view_adult=true
FFF: INFO: 2025-11-03 10:43:52,600: base_otw_adapter.py(194): metaurl: https://archiveofourown.org/works/71694856?view_adult=true
FFF: DEBUG: 2025-11-03 10:43:52,602: cache_basic.py(117):
========== MISS (GET) BasicCache
https://archiveofourown.org/works/71694856/navigate?view_adult=true
FFF: DEBUG: 2025-11-03 10:43:52,602: fetcher_requests.py(114):
---------- REQ (GET) RequestsFetcher
https://archiveofourown.org/works/71694856/navigate?view_adult=true
FFF: DEBUG: 2025-11-03 10:43:52,845: fetcher_requests.py(127): response code:200
FFF: DEBUG: 2025-11-03 10:43:52,845: decorators.py(118): fromcache:False
FFF: DEBUG: 2025-11-03 10:43:52,846: decorators.py(129): random sleep(2.00-6.00):3.13
FFF: DEBUG: 2025-11-03 10:43:55,976: requestable.py(55): Encoding:utf8
FFF: DEBUG: 2025-11-03 10:43:55,977: cache_basic.py(117):
========== MISS (GET) BasicCache
https://archiveofourown.org/works/71694856?view_adult=true
FFF: DEBUG: 2025-11-03 10:43:55,978: fetcher_requests.py(114):
---------- REQ (GET) RequestsFetcher
https://archiveofourown.org/works/71694856?view_adult=true
FFF: DEBUG: 2025-11-03 10:43:56,143: fetcher_requests.py(127): response code:200
FFF: DEBUG: 2025-11-03 10:43:56,143: decorators.py(118): fromcache:False
FFF: DEBUG: 2025-11-03 10:43:56,144: decorators.py(129): random sleep(2.00-6.00):2.92
FFF: DEBUG: 2025-11-03 10:43:59,064: requestable.py(55): Encoding:utf8
FFF: DEBUG: 2025-11-03 10:43:59,066: cache_basic.py(117):
========== MISS (GET) BasicCache
https://archiveofourown.org/token_dispenser.json
FFF: DEBUG: 2025-11-03 10:43:59,066: fetcher_requests.py(114):
---------- REQ (GET) RequestsFetcher
https://archiveofourown.org/token_dispenser.json
FFF: DEBUG: 2025-11-03 10:43:59,138: fetcher_requests.py(127): response code:200
FFF: DEBUG: 2025-11-03 10:43:59,138: decorators.py(118): fromcache:False
FFF: DEBUG: 2025-11-03 10:43:59,139: decorators.py(129): random sleep(2.00-6.00):2.43
FFF: DEBUG: 2025-11-03 10:44:01,573: requestable.py(55): Encoding:utf8
FFF: INFO: 2025-11-03 10:44:01,574: base_otw_adapter.py(138): Will now login to URL (https://archiveofourown.org/users/login) as (XXXXXXX)
FFF: DEBUG: 2025-11-03 10:44:01,574: cache_basic.py(117):
========== MISS (POST) BasicCache
https://archiveofourown.org/users/login
FFF: DEBUG: 2025-11-03 10:44:01,575: fetcher_requests.py(114):
---------- REQ (POST) RequestsFetcher
https://archiveofourown.org/users/login
FFF: DEBUG: 2025-11-03 10:44:03,178: fetcher_requests.py(127): response code:200
FFF: DEBUG: 2025-11-03 10:44:03,178: decorators.py(118): fromcache:False
FFF: DEBUG: 2025-11-03 10:44:03,179: decorators.py(129): random sleep(2.00-6.00):4.45
FFF: DEBUG: 2025-11-03 10:44:07,626: requestable.py(55): Encoding:utf8
FFF: DEBUG: 2025-11-03 10:44:07,627: cache_basic.py(117):
========== MISS (GET) BasicCache
https://archiveofourown.org/works/71694856/navigate?view_adult=true
FFF: DEBUG: 2025-11-03 10:44:07,628: fetcher_requests.py(114):
---------- REQ (GET) RequestsFetcher
https://archiveofourown.org/works/71694856/navigate?view_adult=true
FFF: DEBUG: 2025-11-03 10:44:07,735: fetcher_requests.py(127): response code:200
FFF: DEBUG: 2025-11-03 10:44:07,735: decorators.py(118): fromcache:False
FFF: DEBUG: 2025-11-03 10:44:07,736: decorators.py(129): random sleep(2.00-6.00):5.87
FFF: DEBUG: 2025-11-03 10:44:13,608: requestable.py(55): Encoding:utf8
FFF: DEBUG: 2025-11-03 10:44:13,610: cache_basic.py(117):
========== MISS (GET) BasicCache
https://archiveofourown.org/works/71694856?view_adult=true
FFF: DEBUG: 2025-11-03 10:44:13,610: fetcher_requests.py(114):
---------- REQ (GET) RequestsFetcher
https://archiveofourown.org/works/71694856?view_adult=true
FFF: DEBUG: 2025-11-03 10:44:13,907: fetcher_requests.py(127): response code:200
FFF: DEBUG: 2025-11-03 10:44:13,907: decorators.py(118): fromcache:False
FFF: DEBUG: 2025-11-03 10:44:13,907: decorators.py(129): random sleep(2.00-6.00):5.41
FFF: DEBUG: 2025-11-03 10:44:19,320: requestable.py(55): Encoding:utf8
FFF: DEBUG: 2025-11-03 10:44:19,432: base_otw_adapter.py(324): numChapters: (3)
FFF: INFO: 2025-11-03 10:44:19,561: base_writer.py(194): Save directly to file: Ionic Bonds-ao3_71694856.epub
FFF: DEBUG: 2025-11-03 10:44:19,562: base_otw_adapter.py(486): Getting chapter text for: https://archiveofourown.org/works/71694856/chapters/186628311 index: 0
FFF: DEBUG: 2025-11-03 10:44:19,563: base_otw_adapter.py(500): USE view_full_work
FFF: DEBUG: 2025-11-03 10:44:19,564: cache_basic.py(117):
========== MISS (GET) BasicCache
https://archiveofourown.org/works/71694856?view_full_work=true&view_adult=true
FFF: DEBUG: 2025-11-03 10:44:19,564: fetcher_requests.py(114):
---------- REQ (GET) RequestsFetcher
https://archiveofourown.org/works/71694856?view_full_work=true&view_adult=true
FFF: DEBUG: 2025-11-03 10:44:19,798: fetcher_requests.py(127): response code:200
FFF: DEBUG: 2025-11-03 10:44:19,798: decorators.py(118): fromcache:False
FFF: DEBUG: 2025-11-03 10:44:19,798: decorators.py(129): random sleep(2.00-6.00):4.38
FFF: DEBUG: 2025-11-03 10:44:24,184: requestable.py(55): Encoding:utf8
FFF: DEBUG: 2025-11-03 10:44:24,319: base_otw_adapter.py(486): Getting chapter text for: https://archiveofourown.org/works/71694856/chapters/189126896 index: 1
FFF: DEBUG: 2025-11-03 10:44:24,320: base_otw_adapter.py(500): USE view_full_work
FFF: DEBUG: 2025-11-03 10:44:24,354: base_otw_adapter.py(486): Getting chapter text for: https://archiveofourown.org/works/71694856/chapters/191625151 index: 2
FFF: DEBUG: 2025-11-03 10:44:24,356: base_otw_adapter.py(500): USE view_full_work
FFF: INFO: 2025-11-03 10:44:24,404: writer_epub.py(395): Saving EPUB Version 2.0
FFF: DEBUG: 2025-11-03 10:44:24,488: cli.py(63): Successfully wrote 'Ionic Bonds-ao3_71694856.epub'
Fairly obvious that the CLI manages to correctly log in while the plugin does not under otherwise (outwardly) identical conditions. Prompt for Pillow/continue aside, it's basically the same until the cache miss in both cases, but here it diverges with the plugin getting me 403, while the CLI happily goes on.
(Side note: in the plugin log above, I had basic cache turned off explicitly during one of my attempts, but it was the same behavior with it on.)
All requests are coming from the same machine, no VPN or other shenanigans involved. I can log in to AO3 just fine from my browser using the same account, so I'm not inclined to believe that I've been blocked due to excessive traffic. Haven't even downloaded masses of stories recently, so I don't know why that would be the case.