Jottacloud native backend – sudden increase in HTTP 429 Too Many Requests

I have been using Duplicati with the native Jottacloud backend for quite some time without significant problems.

Within approximately the last month I have started getting frequent:

HttpRequestException: Response status code does not indicate success: 429 (Too Many Requests)

Duplicati version:
2.3.0.4_stable_2026-07-09

I originally had multiple asynchronous uploads enabled. Reducing:

asynchronous-concurrent-upload-limit

to 2 significantly reduced the number of 429 errors, but they still occur and occasionally cause the entire backup to fail.

I have also subsequently seen:

HttpRequestException: Error while copying content to a stream

and local database consistency errors after failed backups.

I am using the native Jottacloud backend, not rclone.

Has anyone else using Jottacloud noticed an increase in HTTP 429 responses during the last few weeks?

Has anything changed recently in either:

  • Jottacloud API / rate limiting
  • Duplicati’s Jottacloud backend
  • asynchronous upload handling in 2.3.x?

Is there any known rate limit for Jottacloud, or a recommended concurrency setting?

I can provide verbose / HTTP request logs if useful.

I can confirm exactly the same behavior with the native Jottacloud backend.

The problem started for me a few weeks ago, before I updated Duplicati, and the update to 2.3.0.4 did not resolve it.

Some observations from my testing:

  • --synchronous-upload=True does not seem to make any difference.

  • The advanced option asynchronous-concurrent-upload-limit is not listed in the dropdown in my installation.

  • I do have asynchronous-upload-limit. A value of 4 no longer works reliably, and neither does 3.

  • Setting asynchronous-upload-limit=2 works most of the time, but not 100% reliably. In particular, it may still fail if I previously attempted the backup with 4 or 3 and that attempt failed.

  • The errors I am seeing are the same: HTTP 429 and “Error while copying content to a stream”.

I also asked Jottacloud’s support bot about upload concurrency. It states that Jottacloud’s own clients use a limit of 6 concurrent uploads and refers to their fair use policy, but it does not provide an exact concurrency limit for third-party clients.

So my experience strongly suggests that something changed on the Jottacloud side a few weeks ago regarding rate limiting or concurrent uploads. At least in my case, reducing Duplicati to 2 concurrent uploads makes the native Jottacloud backend substantially more reliable, although it does not completely eliminate the issue.gewählte option

Thanks, this matches my experience almost exactly.
The issue also started for me only within the last few weeks, and I am seeing both HTTP 429 and “Error while copying content to a stream” with the native Jottacloud backend.
Reducing concurrent uploads to 2 has improved reliability considerably, but has not eliminated the problem.

That makes me suspect a recent change in Jottacloud’s rate limiting or concurrency handling rather than a Duplicati-specific regression.

I have the same problem since about 3-4 weeks.
SulfurRacoon and ning42 summerized it pretty good.

The only thing I can add: If I try to to test the connection I get the 429 as well.

System.Net.Http.HttpRequestException: Response status code does not indicate success: 429 (Too Many Requests).
   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at Duplicati.Library.JsonWebHelperHttpClient.GetResponseAsync(HttpRequestMessage req, HttpCompletionOption httpCompletionOption, CancellationToken cancellationToken)
   at Duplicati.Library.JsonWebHelperHttpClient.GetResponseAsync(HttpRequestMessage req, HttpCompletionOption httpCompletionOption, CancellationToken cancellationToken)
   at Duplicati.Library.Backend.Jottacloud.PutAsync(String remotename, Stream stream, CancellationToken cancelToken)
   at Duplicati.Library.Backend.Jottacloud.PutAsync(String remotename, Stream stream, CancellationToken cancelToken)
   at Duplicati.Library.Main.Backend.BackendManager.PutOperation.PerformUploadAsync(IBackend backend, String hash, Int64 size, CancellationToken cancelToken)
   at Duplicati.Library.Main.Backend.BackendManager.PutOperation.ExecuteAsync(IBackend backend, CancellationToken cancelToken)
   at Duplicati.Library.Main.Backend.BackendManager.PutOperation.ExecuteAsync(IBackend backend, CancellationToken cancelToken)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.ExecuteAsync[TResult](PendingOperation`1 op, CancellationToken cancellationToken)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.ExecuteAsync(PendingOperationBase op, CancellationToken cancellationToken)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.ExecuteWithRetryAsync(PendingOperationBase op, CancellationToken cancellationToken)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.ExecuteWithRetryAsync(PendingOperationBase op, CancellationToken cancellationToken)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.ReclaimCompletedTasksAsync(List`1 tasks)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.EnsureAtMostNActiveTasksAsync(Int32 n, List`1 tasks)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.EnsureAtMostNActiveTasksAsync(Int32 uploads, Int32 downloads)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.RunAsync(IReadChannel`1 requestChannel)
   at Duplicati.Library.Main.Backend.BackendManager.PutAsync(VolumeWriterBase volume, IndexVolumeWriter indexVolume, Func`1 indexVolumeFinished, Boolean waitForComplete, Func`1 onDbUpdate, CancellationToken cancelToken)
   at Duplicati.Library.Main.Operation.Backup.DataBlockProcessor.<>c__DisplayClass1_0.<<RunAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Duplicati.Library.Main.Operation.Backup.DataBlockProcessor.<>c__DisplayClass1_0.<<RunAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at CoCoL.AutomationExtensions.RunTask[T](T channels, Func`2 method, Boolean catchRetiredExceptions)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.RunAsync(IReadChannel`1 requestChannel)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.<>c__DisplayClass14_0.<<RunHandlerAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at CoCoL.AutomationExtensions.RunTask[T](T channels, Func`2 method, Boolean catchRetiredExceptions)
   at Duplicati.Library.Main.Operation.BackupHandler.RunMainOperationAsync(Channels channels, ISourceProvider source, UsnJournalService journalService, BackupDatabase database, IBackendManager backendManager, BackupStatsCollector stats, Options options, IFilter filter, BackupResults result, ITaskReader taskreader, Int64 filesetid, Int64 lastfilesetid)
   at Duplicati.Library.Main.Operation.BackupHandler.RunAsync(String[] sources, IBackendManager backendManager, IFilter filter)
   at Duplicati.Library.Main.Operation.BackupHandler.RunAsync(String[] sources, IBackendManager backendManager, IFilter filter)
   at Duplicati.Library.Main.Operation.BackupHandler.RunAsync(String[] sources, IBackendManager backendManager, IFilter filter)
   at Duplicati.Library.Main.Operation.BackupHandler.RunAsync(String[] sources, IBackendManager backendManager, IFilter filter)
   at Duplicati.Library.Main.Controller.<>c.<<BackupAsync>b__23_0>d.MoveNext()
--- End of stack trace from previous location ---
   at Duplicati.Library.Main.Controller.RunActionAsync[TRes,TCon](TRes result, String[] paths, IFilter filter, TCon context, Func`2 method)
   at Duplicati.Library.Main.Controller.RunActionAsync[TRes,TCon](TRes result, String[] paths, IFilter filter, TCon context, Func`2 method)
   at Duplicati.Library.Main.Controller.RunActionAsync[TRes,TCon](TRes result, String[] paths, IFilter filter, TCon context, Func`2 method)
   at Duplicati.Library.Main.Controller.BackupAsync(String[] inputsources, IFilter inputFilter)
   at Duplicati.Server.Runner.RunInternalAsync(Connection databaseConnection, EventPollNotify eventPollNotify, INotificationUpdateService notificationUpdateService, IProgressStateProviderService progressStateProviderService, IApplicationSettings applicationSettings, IRunnerData data, Boolean fromQueue)
   at Duplicati.WebserverCore.Services.QueueRunnerService.RunTaskAsync(IQueuedTask task)

Thank you for this post.

After setting asynchronous-concurrent-upload-limit and asynchronous-upload-limit to 1 - the backup completed succesfully. Duplicati - 2.0.8.1_beta_2024-05-07.

Tried to create a new backup and got another 429.

Was just trying to create a new folder from duplicati

Failed to connect: error-id:TestWriteError, user-information:Fehler beim Schreiben der Datei: duplicati-access-privileges-test.txt, Fehler: Response status code does not indicate success: 429 (Too Many Requests).

Did another test.

Created a new token from Jottacloud website, created a new backup in Duplicati, just with asyncronous-upload-limit=1, run it and it failed with 429 too.

Help for those used to claim different effects, but asynchronous-upload-limit had none, so currently (as of 2.3) help says the same thing of controlling the number of concurrent uploads:

  --asynchronous-upload-limit (Integer): The number of concurrent uploads allowed
    When performing asynchronous uploads, the maximum number of concurrent uploads allowed. Set to zero to disable the limit.
    * aliases: --asynchronous-concurrent-upload-limit
    * default value: 4

Possibly a side effect of it becoming an alias?

Hopefully the typo is only on forum post.

This seems a good idea, as backups vary. A predictable failure always helps the developers.

They didn’t used to publish one and I don’t see one now, so this makes operations challenging.
They did a change in 2022, where workaround was to use rclone version of Jottacloud support:

Jottacloud

Rclone Destination

Duplicati has a wide variety of storage destinations, but the Rclone project has even more! If you are familiar with Rclone, you can configure Duplicati to utilize Rclone to transfer files and extend to the full set of destinations supported by Rclone.

Tried it. Failed constantly with error 409. Couldn’t figure out why.

Yes, just a typo in this post.

Tried to change the remote volume size down to 50MB instead of 150MB.
Now it fails with Error while copying content to a stream.

I’m giving up for now and hope some future version fixes it.

Can you clarify “error 409”? Did rclone alone say something like that? There are reports, e.g.

HTTP 409 errors Jottacloud (crypt) (rclone forum including sample message found by user)

Google AI Overview for jottacloud error 409 cited that then made claims about how to avoid.

That was shown as Duplicati message in original post. I’m not sure who made an error 409.

I’m not sure how Duplicati rclone backend passes rclone messages along. Might be unclear
which program made the message, or maybe it’s clear? You can describe or post message.

I don’t have Jottacloud. The developers appear to, or at least it looks like a test is available:

duplicati/LiveTests/Duplicati.Backend.Tests/JottaCloud/JottaCloudTests.cs at master · duplicati/duplicati · GitHub

That looks like it runs what a sufficiently determined user or developer could run on their CLI:

BackendTester
and there’s also
BackendTool

If the error 409 looks like rclone can get it without Duplicati, somebody could ask their forum.
OTOH there seems to be some information on it already, per the Google query that I posted.

I had previously done a quick search in rclone forum for 429 errors in timeframe we saw it in.
Didn’t find one, although I did come across other changes to fix various Jottacloud problems.

Update from Jottacloud support

I opened a support case with Jottacloud and they escalated it to their technical team.

They have confirmed that the HTTP 429 responses are caused by rate limiting on the number of requests on the Jottacloud side.

They also explicitly clarified that this is separate from the upload bandwidth limitation that can apply to larger Personal accounts.

They indicated that stricter limits may apply to accounts with large amounts of stored data, but so far they have not provided the actual request-rate threshold.

I have asked them if they can provide the concrete rate limit, or at least recommended request/concurrency values. In the hope that i can configure Duplicati to be configured to stay within the limit instead of repeatedly hitting HTTP 429.

I will update the thread if they provide more technical details.

Thanks for pursuing this, and credit to Jottacloud for not immediately turning away third parties.

Rate limiting is done in various ways. OneDrive uses a Retry-After header to say what it wants.
Google search isn’t finding that for Jottacloud API, but note that it’s not published. Who knows?
OneDrive also seems to have memory, e.g. you can burst, but then get slowed down for awhile.

One thing that Duplicati does that bothers some servers is to retry after 10 seconds (by default).
Some servers call for backoff, so retry-delay got retry-with-exponential-backoff option.

Rclone (whose status on error 409 is TBD) has options to control pacer which does rate limiting.

Found that post too while searching for that error.
I assume the root cause is the same as the 429 error from Duplicati.

My bad. Should have been clearer, but was in a hurry.
I generated a new token at jottacloud, created a new backup with that token and Duplicati errors out with that message.
I used small files (50MB) and limited to one upload.

Thanks for chasing it down with the jottacloud support.
I have large amounts of stored data.

But why get I blocked right away? I don’t even have the chance to upload something.

I wouldn’t assume that. Assuming it’s an HTTP error it’s a different one, however one potential common thread is that more concurrency could possibly aggravate the 409 as well as the 429:

409 Conflict

429 Too Many Requests

I’m still trying to learn whose message it is. Does it look like Duplicati passing rclone message?
Can you get it with just rclone? If you can, then see older rclone suggestions or ask their forum.

It’s your report that “test the connection” causes 429. That’s probably almost no data, but maybe rapid sequencing (potential 409 by much work on one file – although that would seem common).

Have you used much Jottacloud in the last day? OneDrive has memory. Maybe also Jottacloud?

Ultimately, this is probably something best explained by them, then we look for some avoidance.
Sometimes vendors don’t want to say. Reasons might be potential change, fairness, economics.

for what it’s worth here’s what I’m seeing with my backups:

429 happens if:

  • new data is uploaded. While the dblock file is uploaded successfully the dindex subsequently fails with 429

429 does not happen if:

  • a backup is restored (multiple remote files downloaded to do so)

given the lack of interest from developer of this tool I assume that everyone using Jottacloud as backend has to go and look for another solution?