Issues connecting to Microsoft OneDrive on Debian

Hi,
I am using Duplicati on my Debian server for year to backup my files to a OneDrive (personal) folder. After an update to the latest stable (or even the latest Canary) version, I am not able to connect to destination anymore. Anybody also facing issues with OneDrive on Linux?

I tried to connect to OneDrive using a Windows 11 system and it is working normally.

In livelog there is this message:

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: NotTimeValid
   at System.Net.Security.SslStream.SendAuthResetSignal(ReadOnlySpan`1 alert, ExceptionDispatchInfo exception)
   at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at Duplicati.Library.OAuthHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
   at Duplicati.Library.Backend.MicrosoftGraphBackend.SendRequestAsync[T](HttpRequestMessage request, CancellationToken cancelToken)
   at Duplicati.Library.Backend.MicrosoftGraphBackend.SendRequestAsync[T](HttpMethod method, String url, CancellationToken cancelToken)
   at Duplicati.Library.Utility.Utility.WithTimeout[T](TimeSpan timeout, CancellationToken token, Func`2 func)
   at Duplicati.Library.Backend.MicrosoftGraphBackend.Enumerate[T](String url, CancellationToken cancelToken)+MoveNext()
   at Duplicati.Library.Backend.MicrosoftGraphBackend.Enumerate[T](String url, CancellationToken cancelToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
   at Duplicati.Library.Backend.MicrosoftGraphBackend.ListAsync(CancellationToken cancelToken)+MoveNext()
   at Duplicati.Library.Backend.MicrosoftGraphBackend.ListAsync(CancellationToken cancelToken)+MoveNext()
   at Duplicati.Library.Backend.MicrosoftGraphBackend.ListAsync(CancellationToken cancelToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
   at System.Linq.AsyncEnumerable.<ToListAsync>g__Core|424_0[TSource](IAsyncEnumerable`1 source, CancellationToken cancellationToken) in /_/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToList.cs:line 36
   at System.Linq.AsyncEnumerable.<ToListAsync>g__Core|424_0[TSource](IAsyncEnumerable`1 source, CancellationToken cancellationToken) in /_/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToList.cs:line 36
   at Duplicati.Library.Main.Backend.BackendManager.ListOperation.ExecuteAsync(IBackend backend, CancellationToken cancelToken)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.Execute[TResult](PendingOperation`1 op, CancellationToken cancellationToken)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.Execute(PendingOperationBase op, CancellationToken cancellationToken)
   at Duplicati.Library.Main.Backend.BackendManager.Handler.ExecuteWithRetry(PendingOperationBase op, CancellationToken cancellationToken)
   at Duplicati.Library.Main.Backend.BackendManager.ListAsync(CancellationToken cancelToken)
   at Duplicati.Library.Main.Operation.FilelistProcessor.RemoteListAnalysis(IBackendManager backendManager, Options options, LocalDatabase database, IDbTransaction transaction, IBackendWriter log, IEnumerable`1 protectedFiles, IEnumerable`1 strictExcemptFiles, VerifyMode verifyMode)
   at Duplicati.Library.Main.Operation.RepairHandler.RunRepairRemoteAsync(IBackendManager backendManager, CancellationToken cancellationToken)
   at Duplicati.Library.Main.Operation.RepairHandler.RunAsync(IBackendManager backendManager, IFilter filter)
   at Duplicati.Library.Utility.Utility.Await(Task task)
   at Duplicati.Library.Main.Controller.RunAction[T](T result, String[]& paths, IFilter& filter, Func`3 method)
   at Duplicati.Library.Main.Controller.RunAction[T](T result, IFilter& filter, Func`3 method)
   at Duplicati.Library.Main.Controller.Repair(IFilter filter)
   at Duplicati.CommandLine.Commands.Repair(TextWriter outwriter, Action`1 setup, List`1 args, Dictionary`2 options, IFilter filter)
   at Duplicati.CommandLine.Program.ParseCommandLine(TextWriter outwriter, Action`1 setup, Boolean& verboseErrors, String[] args)
   at Duplicati.CommandLine.Program.RunCommandLine(TextWriter outwriter, TextWriter errwriter, Action`1 setup, String[] args)

These issues occur with an existing backup configuration and also while creating a new one. I am using the default OAuth provider (Duplicati OAuth Handler)

Not sure, which certificate is causing the issue.

I am open to any suggestions :wink:
Thanks and BR Heinrich

We do have CI running with Linux and OneDrive, so it “should work”.

Could you try something like this on the problematic machine:

curl -vvv https://graph.microsoft.com
curl -vvv https://duplicati-oauth-handler.appspot.com

One of those commands should return some certificate validation issue.

Did you install from the .deb package? It should pull the ca-certificates package which has the most recent browser certificates.

Yes, installation was done using the .deb package, followed by a apt install -f to ensure all requirements are met… package ca-certificates was installed.
I ran both curl commands, no errors:

root@host:~# curl -vvv https://graph.microsoft.com
*   Trying [2603:1026:3000:a0::84]:443...
* Connected to graph.microsoft.com (2603:1026:3000:a0::84) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: C=US; ST=Washington; L=Redmond; O=Microsoft Corporation; CN=graph.microsoft.com
*  start date: May 10 00:00:00 2025 GMT
*  expire date: Nov 10 23:59:59 2025 GMT
*  subjectAltName: host "graph.microsoft.com" matched cert's "graph.microsoft.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert SHA2 Secure Server CA
*  SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: graph.microsoft.com]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x5581915a67a0)
> GET / HTTP/2
> Host: graph.microsoft.com
> user-agent: curl/7.88.1
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 301
< location: https://developer.microsoft.com/graph
< strict-transport-security: max-age=31536000
< request-id: c6dfc758-a6bc-4f9d-862a-1176be765a68
< client-request-id: c6dfc758-a6bc-4f9d-862a-1176be765a68
< x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"Germany West Central","Slice":"E","Ring":"4","ScaleUnit":"001","RoleInstance":"FR2PEPF000001E1"}}
< date: Thu, 26 Jun 2025 10:02:56 GMT
< content-length: 0
<
* Connection #0 to host graph.microsoft.com left intact

and

root@host:~# curl -vvv https://duplicati-oauth-handler.appspot.com
*   Trying [2a00:1450:4001:810::2014]:443...
* Connected to duplicati-oauth-handler.appspot.com (2a00:1450:4001:810::2014) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=*.appspot.com
*  start date: Jun  2 08:35:19 2025 GMT
*  expire date: Aug 25 08:35:18 2025 GMT
*  subjectAltName: host "duplicati-oauth-handler.appspot.com" matched cert's "*.appspot.com"
*  issuer: C=US; O=Google Trust Services; CN=WE2
*  SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: duplicati-oauth-handler.appspot.com]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x5598baa837a0)
> GET / HTTP/2
> Host: duplicati-oauth-handler.appspot.com
> user-agent: curl/7.88.1
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/2 200
< content-type: text/html; charset=utf-8
< vary: Accept-Encoding
< x-cloud-trace-context: 64d2e6d4bf834e6a9677d614f07a7cd8
< date: Thu, 26 Jun 2025 10:03:34 GMT

using openssl also indicates, that the chain can be validated sucessfully:

root@host:~# openssl s_client -connect duplicati-oauth-handler.appspot.com:443
CONNECTED(00000003)
depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R4
verify return:1
depth=1 C = US, O = Google Trust Services, CN = WE2
verify return:1
depth=0 CN = *.appspot.com
verify return:1
---
Certificate chain
 0 s:CN = *.appspot.com
   i:C = US, O = Google Trust Services, CN = WE2
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA256
   v:NotBefore: Jun  2 08:35:19 2025 GMT; NotAfter: Aug 25 08:35:18 2025 GMT
 1 s:C = US, O = Google Trust Services, CN = WE2
   i:C = US, O = Google Trust Services LLC, CN = GTS Root R4
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA384
   v:NotBefore: Dec 13 09:00:00 2023 GMT; NotAfter: Feb 20 14:00:00 2029 GMT
 2 s:C = US, O = Google Trust Services LLC, CN = GTS Root R4
   i:C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA
   a:PKEY: id-ecPublicKey, 384 (bit); sigalg: RSA-SHA256
   v:NotBefore: Nov 15 03:43:21 2023 GMT; NotAfter: Jan 28 00:00:42 2028 GMT

and

root@host:~# openssl s_client -connect graph.microsoft.com:443
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
verify return:1
depth=0 C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = graph.microsoft.com
verify return:1
---
Certificate chain
 0 s:C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = graph.microsoft.com
   i:C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: May 10 00:00:00 2025 GMT; NotAfter: Nov 10 23:59:59 2025 GMT
 1 s:C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
   i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Sep 23 00:00:00 2020 GMT; NotAfter: Sep 22 23:59:59 2030 GMT

are there any other URLs involved?

interestingly - I do have a second Debian (stable) system - there Duplicati is running without any issue…
patch level of both system is equal - I ran update-ca-certificates -f on both systems - 142 certificates were added (on both systems)…

I just checked the code again, and based on the stack trace, it is not the OAuth handler that is causing issues.

The initial request goes to the graph endpoint as best as I can see, but it is possible that it is redirected after authentication.

To collect tracing information, you can try restarting Duplicati with this setup:

export DOTNET_EnableEventPipe=1
export DOTNET_EventPipeConfig=System.Net.Http:0xFFFFFFFFFFFFFFFF:5
export DOTNET_EventPipeOutputPath=/tmp/http_{pid}.nettrace
export DOTNET_EventPipeOutputStreaming=1   # write as it runs
duplicati

This should generate a file in /tmp/http_*.nettrace that you can inspect. With tracing activated, try to connect to OneDrive and the trace file should have a line that looks like:

RequestFailed: https://example.com - UntrustedRoot

The domain and failure message will hopefully get us closer to understanding what the problem is.

Hi @kenkendk,
thanks for digging into my issue. I just finished some further tests and troubleshooting using strace and tcpdump:
Seems, that the issue was related to an expired TLS certificate of my system. If I understand my dump correctly, my system tries to authenticate at Microsoft’s graph endpoint using an old TLS certificate.

After cleaning up /etc/ssl/certs and removing my own expired certificates, the connection to OneDrive finally works.

If it’s helpful I would be happy to provide the pcap-file or create the trace file as you described… But I am also fine with “let it go, it’s working, now”…

Thank you for your support!
BR Heinrich

It sounds like this was an issue with your system and since it is not a general issue I don’t need trace files.

If someone else reports the same problem, at least there is now a way to fix it, so thanks a bunch for reporting the solution!