Token refresh process and --bind option

What is the problem you are having with rclone?

On a Onedrive backend, I’m using –bind 0.0.0.0 for my rclone mount. Traffic (uploads and downloads) are using ipv4 as expected, but on Entra, ipv6 is still used in the enterprise app used by rclone. Is this normal ? Token refresh process are not honoring “bind” ? My guess is the token refresh process is using the web browser flow / localhost, and since localhost is resolving with ipv6 first, then it’s communicating with the apps in ipv6 ? Any way to change this ? Thx you :slight_smile:

Run the command 'rclone version' and share the full output of the command.

rclone v1.73.0-beta.9407.824257583

  • os/version: Microsoft Windows 11 Enterprise 25H2 25H2 (64 bit)
  • os/kernel: 10.0.26200.7623 (x86_64)
  • os/type: windows
  • os/arch: amd64
  • go/version: go1.25.6
  • go/linking: static
  • go/tags: cmount

Which cloud storage system are you using?

OneDrive Business with a dedicated apps created in my tenant.

The command you were trying to run (eg rclone copy /tmp remote:tmp)

C:\rclone-browser-1.2-a1156a0-win64\rclone.exe mount secure-vault: O: ^
  --cache-dir t:\mountcache ^
  --attr-timeout 8700h ^
  --stats 10s ^
  --buffer-size 256M ^
  --vfs-cache-poll-interval 30s ^
  --poll-interval 30s ^
  --no-console ^
  --dir-cache-time 30m ^
  --vfs-cache-max-age 24h ^
  --async-read=true ^
  --vfs-cache-mode full ^
  --vfs-read-chunk-size 64M ^
  --vfs-read-chunk-size-limit 2G ^
  --vfs-read-ahead 256M ^
  --use-mmap ^
  --local-no-check-updated ^
  --multi-thread-streams=4 ^
  --multi-thread-cutoff 250M ^
  --transfers 8 ^
  --fast-list ^
  --vfs-case-insensitive ^
  --vfs-cache-max-size 125G ^
  --log-level ERROR ^
  --log-file="c:\rclonelog\rclonemountunion.txt" ^
  --rc ^
  --rc-addr=127.0.0.1:5575 ^
  --tpslimit 10 ^
  --tpslimit-burst 0 ^
  --vfs-refresh ^
  --onedrive-delta ^
  --network-mode ^
  --bind 0.0.0.0 ^
  --disable-http2 ^
  --links ^
  -o FileInfoTimeout=-1

Please run 'rclone config redacted' and share the full output. If you get command not found, please make sure to update rclone.

[onedrive-e5-2-user]
type = onedrive
client_id = XXX
client_secret = XXX
tenant = XXX
drive_type = business
token = XXX
drive_id = XXX

[onedrive-e5-3-user]
type = onedrive
client_id = XXX
client_secret = XXX
tenant = XXX
drive_id = XXX
drive_type = business
token = XXX

[onedrive-e5-4-user]
type = onedrive
client_id = XXX
client_secret = XXX
tenant = XXX
drive_id = XXX
drive_type = business
token = XXX

[onedrive-e5-user]
type = onedrive
tenant = XXX
drive_id = XXX
drive_type = business
client_id = XXX
client_secret = XXX
token = XXX

[secure-vault]
type = crypt
remote = union-rand:
password = XXX
filename_encryption = standard
directory_name_encryption = true
filename_encoding = base32768

[union-rand]
type = union
search_policy = ff
upstreams = onedrive-e5-user: onedrive-e5-2-user: onedrive-e5-3-user: onedrive-e5-4-user:
create_policy = mfs
action_policy = ff

A log from the command that you were trying to run with the -vv flag

No errors

Have you tried using bind with the actual IPv4 address? I recall some issues around using 0.0.0.0

Yep, I just tried, waited for an auth, and bingo, it’s ipv6 again.

1 Like

For the record, I tested the mount with a proxy too, and while I see the transferts are using it, the auth are still going out via my public ipv6 address. On the entra side, I confirmed it’s rclone doing theses requests :

Agent utilisateur (user agent) : rclone/v1.73.0-beta.9407.824257583

So I prioritize ipv4 over ipv6, and still, my ipv6 is showing in Entra’s logs. Anybody how rclone is working under the hood :smiley: ?

If it helps, I dumped it into Claud and response was:

The Issue: OAuth Token Refresh Bypasses --bind

The token refresh happens in a separate HTTP context that doesn't honor your bind setting.

Here's the flow:

  1. Your mount traffic (uploads/downloads) correctly uses --bind 0.0.0.0:

    • Goes through fshttp.NewClient(ctx) → Creates transport with bind address

    • LocalAddr is set on the Dialer

  2. OAuth token refresh uses Go's golang.org/x/oauth2 library:

    • The OAuth2 library creates its own HTTP client for token refresh

    • rclone passes a "base client" to oauthutil, but the OAuth2 library wraps it in its own Transport

    • When the token needs refreshing, oauth2.TokenSource makes the request

    • This transport doesn't inherit your bind settings

Why IPv6 Specifically?

When Go's OAuth2 library creates its HTTP client without a LocalAddr binding:

  1. It relies on the OS's default route selection

  2. Your system is dual-stack with IPv6 preferred

  3. Microsoft's Entra endpoint is dual-stack

  4. Go's resolver returns IPv6 address first

  5. Boom - IPv6 connection to login.microsoftonline.com

Even though you set --bind 0.0.0.0, the OAuth library's internal client doesn't see it.

The Root Cause in Code:

Looking at backend/onedrive/onedrive.go:

go

client := fshttp.NewClient(ctx)  // <-- This respects --bind
oAuthClient, ts, err := oauthutil.NewClientWithBaseClient(ctx, name, m, oauthConfig, client)

But inside oauthutil.NewClientWithBaseClient, when setting up the OAuth config:

  • It creates a TokenSource

  • The TokenSource uses oauthConfig.TokenSource(ctx, token) from Go's oauth2 library

  • That TokenSource creates its own HTTP client for refresh operations

Solutions:

Option 1: System-level IPv4 preference

bash

# Prioritize IPv4 in /etc/gai.conf
echo "precedence ::ffff:0:0/96  100" >> /etc/gai.conf

Option 2: Firewall rule (nuclear option) Block IPv6 to Microsoft's OAuth endpoints - forces IPv4

Option 3: Wait for rclone fix This is a known issue (forum post from 3 days ago!). The fix would require rclone to inject the bind-configured transport deeper into the OAuth2 library's refresh mechanism.

Bottom line: It's not you, it's the OAuth library not respecting rclone's transport configuration during token refresh. The PR #8733 won't fix this - that's about the initial OAuth webserver, not the refresh client.

Classic Go OAuth2: "I'll make my own HTTP client, with blackjack and... IPv6." :smirking_face:

Yeah, Kimi 2.5 give me something similar :slight_smile: and added to add the all_proxy variable, but no dice.

It’s on windows, so I even made a qos rules for the rclone.exe process, adding dscp 34 to every packet, and on my mikrotik firewall, I forced theses packets to use the wireguard tunnel. Work like a charm for transferts stuff, but oath is still showing in ipv6, and theses packets are not marked by the qos policy… I’m stunned, like rclone is spawning a whole other process to do that …

I see other products based on go having the same problem, Oauth not respecting the proxy settings, or even using other process on Windows. Some projects are able to fix it, some don’t care. @ncw should I open a issue on Github ? What do you think ? Thx you :slight_smile:

Reading this Non-interactive sign-in logs - Microsoft Entra ID | Microsoft Learn and User sign-ins (non-interactive) Sign-in IP shows mine but the service account is being used from another IP. - Microsoft Q&A , maybe I’ll to make the registration from behind the proxy, for this ip to show in the non interactive signin view.