Hi Nicholas,
Scheduled Akeeba Backup B2 uploads on our Joomla 6 site started failing at post-processing on 2026-05-29. Root cause is on Backblaze's side: they retired API versions 1, 2, and 3 of b2_authorize_account specifically. Only v4 still responds. The Backblaze post-processor in Akeeba Backup 10.3.3 calls v1, so every scheduled run with B2 as the destination now stops at the first authorize call. Small patch attached.
vendor/akeeba/engine/engine/Postproc/Connector/Backblaze.php (line 49) hardcodes /b2api/v1/ as the authorize entry point, and authorizeAccount() at line 805 calls b2_authorize_account against it. As of 2026-05-29:
Backblaze B2 API Error bad_request:
This request is not currently supported on API version number 1
I verified directly against the B2 endpoint with the same key:
| v1 | bad_request: This request is not currently supported on API version number 1 |
| v2 | bad_request: ... version number 2 |
| v3 | bad_request: ... version number 3 |
| v4 | 200 OK, new nested response shape |
The cutoff was narrow: our last successful Akeeba B2 upload finished at 2026-05-28 23:54 UTC; the next scheduled run at 2026-05-29 03:35 UTC hit the rejection. The other Backblaze endpoints used by the connector (b2_get_upload_url, b2_upload_file, b2_list_file_versions, etc.) still respond on v1 today, so the patch only touches the authorize call site and the two response objects.
Every Akeeba Backup install pointed at Backblaze B2 is going to hit this as their scheduled runs fire.
Proposed fixBackblaze.php: changeapiURLfrom/b2api/v1/to/b2api/v4/. The constant is only used byauthorizeAccount(); other endpoints run off the per-accountapiUrlreturned by authorize, unchanged.AccountInformation.php: in the constructor, detect the v4 nested shape and liftapiInfo.storageApi.*back to the top level before the existing property-assignment loop. v1 still works because the lift only triggers whenapiInfo.storageApiis present.Allowed.php: add a$bucketsproperty for the v4allowed.buckets[]array (which replacesbucketId/bucketNamefor multi-bucket-scoped keys). SeedbucketId/bucketNamefrom the first entry so single-bucket callers keep working. UpdateisBucketAllowed()to check the full bucket list when present.
Multi-bucket support in Allowed was necessary in our case because the same runtime key has access to four buckets (GFS rotation). Without it, the seeded bucketName only matches the first bucket and rejects the others.
Full diff attached. 110 lines added, 0 removed. The headline change:
--- Backblaze.php
+++ Backblaze.php
@@ -45,8 +45,19 @@
- /** The API entry point URL, only used to retrieve the authorization token */
- public const apiURL = "https://api.backblazeb2.com/b2api/v1/";
+ /**
+ * The API entry point URL, only used to retrieve the authorization token.
+ * Backblaze retired v1, v2 and v3 of b2_authorize_account around 2026-05-28/29.
+ * Only v4 is accepted now. AccountInformation and Allowed unpack both shapes.
+ */
+ public const apiURL = "https://api.backblazeb2.com/b2api/v4/";
Alternative shapes
- I left the other nine
/b2api/v1/path constants inBackblaze.phpalone because they still respond on v1 today. If you'd rather migrate the whole connector in one pass, it is mechanical; I can attach a broader patch. - The v4 backward-compat path in
AccountInformationandAllowedcould be removed once it is clear Backblaze is not rolling v1 back. I kept it for safety during the rollover window.
Patched on our production install, verified end-to-end via Akeeba's composer autoloader against a fresh v4 authorize response and confirmed multi-bucket isBucketAllowed() behaves correctly. Tonight's scheduled GFS daily will exercise the full B2 upload path live.
Thanks for taking a look. Happy to reshape, broaden to migrate the rest of the v1 paths in one go, or drop the backward-compat handling if you'd prefer a cleaner v4-only path.
Brian Mitchell
Intergen