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.