Commit Graph
2042 Commits
Author SHA1 Message Date
Nick Craig-Wood a64c0a0fde build: modernize with "go fix -rangeint": use range over int 2026-08-21 12:23:31 +01:00
Nick Craig-Wood b5bea683c5 build: modernize with "go fix -minmax": use min and max builtins 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 357c2a2b44 build: disable staticcheck SA4023 to fix lint job timeout
The dataflow analysis behind SA4023, new in the staticcheck 0.8.0
bundled with golangci-lint v2.13.0, makes linting large packages more
than 10x slower (89s vs 7s for backend/s3 alone) which took the CI
lint job past its 30 minute limit. golangci-lint no longer enforces
its run timeout during analysis so the job ran until cancelled, and
the cancellation meant the lint cache was never saved, making every
subsequent run cold and guaranteeing the timeout repeated.

The check also produces false positives (eg claiming operations.Delete
never returns nil).
2026-08-21 12:23:31 +01:00
Nick Craig-Wood e189f38122 build: update to go1.27 and make go1.26 the minimum required version 2026-08-20 12:16:48 +01:00
Nick Craig-Wood 2f7d4e3f9f rc: deprecate --rc-web-gui flag
This commit removes the workings of the old web ui which hasn't been
maintained for 6 years. If users supply --rc-web-gui then rclone will
exit with an error pointing users at the maintained `rclone gui`
command.
2026-08-19 12:15:00 +01:00
maxandNick Craig-Wood a1f98b49df asyncreader: run the skip-bytes test under the race detector again
The test skipped every buffer count above 1 under -race, pointing at
golang/go#27070. That issue was closed in September 2018, so the
workaround outlived its cause: -race covered 137 of the 681 subtests.

Without the guard the race build runs all 681 and passes.
2026-08-17 08:13:21 +01:00
Shurong CaoandNick Craig-Wood bb7c081ec5 sync: add pattern-based transfer ordering
Allow --order-by to rank files using comma-separated rclone path globs. Patterns are evaluated in order, unmatched files are placed last, and path ordering makes ties deterministic.

Fixes #3975
2026-08-14 18:47:15 +02:00
MoraxandNick Craig-Wood 9f93da3299 operations: fall back when source ignores ranges
When a multi-thread source ignores ranged reads, abort the partial
destination and retry the copy as a single stream. Reset accounting
before the fallback so transfer progress remains accurate.
2026-08-14 18:40:40 +02:00
MoraxandNick Craig-Wood 69e5aff2a9 lib/rest: validate ranged responses
Add response validation for calls made with Range open options. Verify
Content-Range, Content-Length, response status, and the complete
representation size before a backend accepts the response body.

Return a shared sentinel when a server ignores a partial range so callers
can avoid retrying the same unsupported request.
2026-08-14 18:40:40 +02:00
Pastalikek65andNick Craig-Wood adc7f2ebfa config: redact env var config values in logs
Before this change the environment variable getters in fs/configmap.go
logged the option value with %q, so a password set via
RCLONE_CONFIG_remote_pass (or RCLONE_remote_pass) was printed in full
to the debug log. Values from the config file were already redacted,
which made the leak easy to miss.

This change routes both getters through fs.RedactOptionValue, which
looks up the option in the backend's option list: options marked
IsPassword or Sensitive log as XXX, unknown options are conservatively
redacted, and --dump auth still shows the value for debugging.

Fixes #5794
2026-08-13 20:10:41 +02:00
Teddy TennantandNick Craig-Wood a182fcbce8 operations: speed up checksum by hashing files in parallel - fixes #9727
rclone checksum and rclone check --checkfile hashed one file at a time
unless --download was in use. The non-download branch of CheckSum called
Object.Hash synchronously from inside the listing callback, so --checkers
had no effect there; only the --download branch used the checker token
pool.

Both branches now do their work in the same goroutine bounded by
--checkers, so --checkers means the same thing with and without
--download. Checking a sum file against 2.6 GiB of local files with
--checkers 8 went from 1.70s to 0.31s here.

As a result the "hashing" checking transfer now covers the hashing work
in both branches, rather than being finished as soon as the download
goroutine had been started.
2026-08-13 19:54:45 +02:00
phatlcandNick Craig-Wood fc348fcb0b operations: check checksums in rcat with known size - fixes #6305
RcatSize streams the body straight into Put behind an ObjectInfo with no
hashes, so a known-size upload had its size checked but its checksum
never verified, unlike the unknown-size path through Rcat which hashes as
it goes.

The stream can only be read once, so hash it on the way past and compare
with the destination after the upload, as operations.Copy does. A
destination which reports no usable hash is still checked by size, and one
which fails either check has the failed copy removed.
2026-08-13 19:49:33 +02:00
nielashandNick Craig-Wood abae66ee1a accounting: fix memory leak from stats groups on long-running rcd
Before this change, `NewStats` stored the context it was created from on the
`StatsInfo`. Stats groups are never freed -- they are only evicted once there are
`--max-stats-groups` of them -- so each one kept its context, and everything reachable
from it, alive for the life of the process. As the rc creates a group per call,
that included the call's filters and their compiled regexps.

The context was only ever used to get `ci.StatsFileNameLength` from the config.
`StatsInfo` already stores that same `*fs.ConfigInfo`, read from the same
context in `NewStats`.

This change fixes the issue by passing the stored ci to `transferMap.String` and
dropping the context from `StatsInfo`.
2026-08-11 22:12:51 +02:00
nielashandNick Craig-Wood 71a0932126 accounting: fix memory leak on long-running rcd
Before this change, Transfer.Done closed the account of a completed transfer but
never released it, because it assigned nil to only a local copy of the pointer.
As a result, every completed transfer continued to reference its account.

An Account holds the transfer context and the source reader, and the stats keep
completed transfers around up to `MaxCompletedTransfers` per group, with groups
discarded only at --max-stats-groups. On a long-running `rclone rcd`, this adds up.

It was noticeable when running bisync repeatedly via the rc, where the transfer
context carries `b.WriteResults` (bisync's `LoggerFn`). A `*bisyncRun` holds
Path1 and Path2 listings, which can be quite large, and are not supposed to be
retained between runs. (Naturally they aren't, when running bisync on the
command line -- which is probably why we didn't notice this issue sooner.)

This change fixes the issue by releasing `tr.acc` in Done, instead of the local
copy. `tr.Snapshot` reads the byte counts off the account, so the progress is
recorded on the transfer first. That read happens before taking `tr.mu`, because
`acc.progress()` locks `acc.values.mu`, `checkReadBefore` holds that lock while
calling `StatsInfo.GetBytes`, and `StatsInfo` locks back into `Transfer` in
`Transferred` and `_removeTransfer`.
2026-08-11 22:12:51 +02:00
Nick Craig-Wood 9b13247ba8 operations: fix silent truncation of streaming uploads whose source ends early
Uploads through RcatSize with a known size - used by rcat --size, the
rc operations/uploadfile and the serve backends, eg serve restic - did
not check the size of the uploaded object. If the source stream ended
before the declared size worth of data had been read, the truncated
object was reported as a successful upload. This could corrupt data
for callers which trust the result, eg a restic repository accessed
via serve restic (see #9722).

This adds the same size check operations.Copy performs after a copy,
respecting --ignore-size and backends which do not report sizes.
2026-08-04 19:29:21 +01:00
Nick Craig-Wood 39d8e83a12 Start v1.76.0-DEV development 2026-07-31 18:21:36 +01:00
Nick Craig-Wood 4bb6a1edf6 rc: require authentication to list the remotes with --rc-serve GHSA-mfvx-7rcj-9m5g
With --rc-serve set the root listing enumerated the names of all configured
remotes without any authentication.

Make the root listing obey the same fail-closed rule as the rest of
the rc endpoints: it now requires authentication to be configured or
an explicit opt out with --rc-no-auth.

Addresses GHSA-mfvx-7rcj-9m5g finding 2.
2026-07-31 13:21:59 +01:00
Nick Craig-Wood faaf716e9b rc: don't expose pprof debug handlers on an unauthenticated server GHSA-mfvx-7rcj-9m5g CVE-PENDING
The pprof debug handlers were accessible without authentication disclosing the
process command line (which can carry backend credentials passed on the command
line) and runtime profiles.

Mount the pprof handlers only when when auth is configured or --rc-no-auth was
passed - so they obey the same rule as the rc endpoints.

Addresses GHSA-mfvx-7rcj-9m5g finding 1.
2026-07-31 13:21:59 +01:00
Nick Craig-Wood ff43a1e3ae rc: fix leaking stack traces on panics GHSA-gwfq-86j8-7qhv
Before this change, rclone sent stack traces to the client on panic
capture in the rc. Stack traces can leak information which could be
useful to an attacker.
2026-07-31 13:21:59 +01:00
Yash AnilandNick Craig-Wood bd4c6571ec march: fix goroutine leak on completed async rc jobs - fixes #9620
The march janitor goroutine, which discards queued jobs when the context is
cancelled, only ever returned on context cancellation. A march that finished
normally never cancels its context, so on an async rc job (whose context
descends from context.Background and is only cancelled by job/stop) the
janitor parked forever, leaking one goroutine per run and pinning that run's
directory listings in memory. A long-running rcd driving async sync or bisync
jobs accumulated these until it ran out of memory.

Signal the janitor to exit once the march completes so it returns on both
normal completion and cancellation.
2026-07-29 20:29:13 +01:00
Hakan İSMAİLandNick Craig-Wood a50d1137a3 fs/rc: add ParseOptions and CheckParamsUsed unified options helpers 2026-07-29 19:42:45 +01:00
phatlcandNick Craig-Wood ab93058560 fserrors: make http2 "server sent GOAWAY" a retriable error - fixes #9664
When an HTTP/2 server retires a connection with GOAWAY after it has
already sent successful response headers, Go's http2 transport fails the
read of the response body with

    http2: server sent GOAWAY and closed the connection; LastStreamID=..., ErrCode=NO_ERROR, debug=""

This was not recognised as a retriable networking error, so a transient
connection retirement aborted the whole command instead of consuming a
low level retry. It was reported against a large S3 check, where an
interrupted ListObjectsV2 page made rclone report destination objects as
missing and exit unsuccessfully.

The concrete error type is unexported by net/http, so match on the
message as we already do for the other http2 transport errors.
2026-07-29 17:35:11 +01:00
Søren LindbergandNick Craig-Wood a1d906fd3d operations: fix Move godoc to note Copy fallback is accounted as a transfer - fixes #8799 2026-07-21 16:33:30 +01:00
Nick Craig-Wood 4db5b91610 sync: fix one transform test error failing all the following tests
Sync refuses to delete files when the global error stats are non-zero
so a single backend error in one transform test made every following
transform test in the same test binary fail with "not deleting files
as there were IO errors". Reset the stats at the start of each test.
2026-07-20 17:21:33 +01:00
Nick Craig-Wood ed60580730 sync: fix tests failing on backends that drop hashes on server side copy
ownCloud does not carry the checksum over to the destination of a
server side copy and refuses attempts to set it afterwards, so the
destination legitimately has no hash. The logger vs lsf check
compared the predicted hash against the empty hash and failed.

Treat an empty hash in the listing as unknown rather than wrong,
matching how sync itself compares hashes.
2026-07-17 18:29:39 +01:00
Nick Craig-Wood 8b812fff28 fs: fix passwords and tokens appearing in the debug log during rclone config
Previously running rclone config (or driving it via the rc API or web
GUI) with -vv would write secrets to the debug log.

This was dangerous as users debugging a failing config flow often
paste their -vv logs into the forum or GitHub issues.

These values are now redacted from the log as "XXX". Values whose
option is known are only redacted if the option is marked IsPassword
or Sensitive, so normal answers remain visible.

Use --dump auth to see the unredacted values when debugging a config
flow - rclone prints a warning that secrets will appear in the log
when this is in effect.

This was discovered by CodeQL: https://github.com/rclone/rclone/security/code-scanning/182
2026-07-16 16:11:22 +01:00
Nick Craig-Wood 2eb6f6d961 fs: don't log the contents of objects without a String method
The logging functions take an object which is rendered into the log
line. Rendering it with %+v dumps all its fields, which for an object
holding backend config would include decrypted credentials. Every
object currently logged is a string or has a String method, so render
anything else as just its type to keep credentials out of the logs.

See: https://github.com/rclone/rclone/security/code-scanning/183
2026-07-15 16:43:37 +01:00
dougalandNick Craig-Wood c4d87bd6d4 fs/config: add tier to config wizard
This makes the overview from the docs accessible in the code.
2026-07-14 14:16:19 +01:00
Cao YuhangandNick Craig-Wood 76196a2897 operations: fix core/du test with missing cache dir
TestRcDu relied on the default cache directory already existing. In clean
or container environments diskusage.New returned ENOENT, which the test
ignored before type asserting a nil result.

Use a temporary directory and require a successful response before
checking the disk usage values.
2026-07-14 11:23:58 +01:00
Nick Craig-Wood 9e0a5b66a4 march: fix unnecessarily listing dst directory when src listing finished
When doing a copy (no delete mode) without a logger, the destination
listing can be cancelled as soon as the source listing finishes, since
dst-only entries won't be processed.

This is particularly beneficial with --fast-list where the dst listing
may fetch the entire directory tree upfront via ListR. Cancelling it
early avoids waiting for a potentially large listing that won't be used.

Adds NoProcessDstOnly flag to March which, when set, cancels the dst
listing context once the source channel is exhausted in matchListings.

Fixes #9226
2026-07-12 17:10:10 +01:00
Nick Craig-Wood 2228e7c866 march: add context parameter to listDirFn for cancellable listings #9226
Add a context parameter to listDirFn so that each call site can pass
its own context. The closures in makeListDir previously captured
m.Ctx at creation time; they now use the context passed at call time
instead. This is needed so that processJob can pass a cancellable
context for the destination listing independently of the source.

Note: callers must pass m.Ctx (or a child of it) to preserve the
existing cancellation behaviour where listings stop when the march
context is cancelled.
2026-07-12 17:10:10 +01:00
Nick Craig-Wood c6cdb89935 config: fix normalization when obscuring passwords - fixes #9507
Interactively-entered passwords were run through NFKC Unicode
normalization before being obscured, which silently rewrote characters
such as ª (U+00AA) to a. The obscured password then revealed to
something different from what the user typed confusing everyone.

Normalization is only needed for the config encryption master
password, so apply it there (in SetConfigPassword) rather than in the
shared checkPassword used for backend password options.
2026-07-12 13:27:46 +01:00
Nick Craig-Wood 0a44cbff37 operations: fix operations/stat for directories wth large parent dirs
When `operations/stat` / StatJSON is called on a directory path it
lists the parent directory to find the target entry. If the parent has
millions of entries this is very expensive.

This fixes the problem for bucket-based backends with ListP by listing
the target directory itself first. It will stop the listing
immediately if any files are found meaning it is safe to run on
directories with millions of files.
2026-07-12 13:27:19 +01:00
Nick Craig-Wood 9a49790797 fs/logger: fix flaky tests by generating test data locally
The TestLogger/TestRepoCompare and TestLogger/TestBeforeVsAfter
testscript scenarios filled src and dst by downloading two old rclone
source archives from GitHub with `rclone copyurl`. Whenever GitHub or
the network hiccuped (eg a 502 Bad Gateway) the downloads failed and
the tests failed with it, making them flaky on CI.

Generate two overlapping trees of files in the test Setup instead.
They cover the same comparison categories the scripts exercise
(matching, differing, src-only and dst-only files) so the tests are
just as meaningful but no longer depend on the network.
2026-07-12 13:26:17 +01:00
Nick Craig-Wood d40423765b config: add config unset command to remove options from a remote - fixes #9541
Previously the only way to remove an option from a remote was to set it
to an empty string, which is not the same as deleting it - a present but
empty value overrides the option's default whereas a deleted key
restores it. Editing the file by hand isn't an option for an encrypted
config either.

This adds a "config unset" command and a "config/unset" rc endpoint to
remove one or more keys from an existing remote.
2026-07-10 18:45:41 +01:00
Nick Craig-Wood ed9eec0f20 fs/chunkedreader: fix spurious errors when a parallel stream is closed early
Closing a stream in the parallel chunked reader cancels the stream's
context, so the in-flight read returns context.Canceled. This was wrapped
and returned as "failed to read stream", which the VFS cache downloader
treats as a real download error - it only recognises
asyncreader.ErrorStreamAbandoned as a benign teardown, as returned by the
sequential reader.

Return asyncreader.ErrorStreamAbandoned for a cancellation so tearing down
the parallel reader (on close, seek or reposition) is recognised as benign,
matching the sequential reader, instead of logging download errors and
retrying when --vfs-read-chunk-streams is used with --vfs-cache-mode full.
2026-07-09 17:46:31 +01:00
859439c1e0 config: fix config_template_file and config_template being ignored via config/create - fixes #9572
When creating or updating a remote through the rc api (config/create,
config/update), parameters whose name starts with the ephemeral prefix
"config_" (for example config_template_file and config_template used to
customise the OAuth success page) were silently ignored.

updateRemote sets each supplied parameter into the config mapper, but
skips the "config_" prefixed keys so they are never written to the
config file. That guard is correct, because the mapper's setter writes
to the config file and these values are ephemeral. However backends read
these values back from the mapper (oauthutil reads config_template_file
and config_template via m.Get), so dropping them entirely meant the
values could never reach the backend and the default template was always
used.

Collect the ephemeral parameters into a separate map and add it to the
mapper as a getter overlay at PriorityNormal after the loop. The values
are now readable through m.Get without being written to the config file,
which is the same approach rclone authorize already uses to expose a
template supplied on the command line.

Fixes #9572

Co-authored-by: Hakanbaban53 <93117749+Hakanbaban53@users.noreply.github.com>
Co-authored-by: maximilize <3752128+maximilize@users.noreply.github.com>
2026-07-09 15:44:49 +01:00
Amit MishraandNick Craig-Wood cb41e42d04 fs: fix negative offset when a suffix Range request exceeds object size
A Range header requesting a suffix longer than the object (e.g.
"bytes=-90407" against a 5 byte object) caused RangeOption.Decode to
compute a negative offset (size - End), which serve.Object then used
directly as a slice/seek offset and panicked with "slice bounds out of
range". FixRangeOption (used by backends like OneDrive/Box that lack
native suffix-range support) had the same root cause: it produced a
RangeOption with a negative Start, which Header() silently dropped,
turning the request into the wrong byte range instead of erroring or
serving the whole object.

Per RFC 7233 section 2.1, when the suffix-length exceeds the
representation size, the entire representation should be served.
Clamp the computed offset/start to 0 in both places.

Fixes #6310
2026-07-04 09:11:52 +01:00
blackflytechandNick Craig-Wood b12251f07f chore: fix some function names in comments
Signed-off-by: blackflytech <blackflytech@outlook.com>
2026-07-02 11:30:15 +01:00
GauravandGitHub 761af75a25 filter: add --files-from0 to support NUL-delimited input - fixes #9537 2026-07-02 11:21:21 +01:00
Sanjays2402andNick Craig-Wood c91c4cbbff accounting: fix goroutine leak in NewStatsGroup for zero-transfer rc jobs
NewStatsGroup started the averageLoop goroutine unconditionally at
group creation. In an rcd daemon driven by many short rc sync/move
calls (a common pattern for scheduled spool flushes), each call gets
a fresh job/N stats group. When such a job transferred zero files
the loop was never stopped, because _stopAverageLoop is only reached
via DoneTransferring once transferring and checking both go from
non-empty back to empty, which never happens if nothing was ever
transferring in the first place. The result was one leaked goroutine
per rc call, growing unbounded until the daemon was OOM-killed
(reported: ~61k goroutines and ~640 MB RSS after ~7 days from a
per-minute timer over 6 mappings).

This is the same class of leak as #8571, which fixed the equivalent
auto-start in NewStats. Fix it the same way: do not start the average
loop at group creation. NewTransfer and NewTransferRemoteSize already
call startAverageLoop when real transfer activity begins, and
DoneTransferring already stops it when the last transfer completes,
so on-demand behaviour is unchanged for groups that actually do work.
Groups that never transfer anything now cost zero goroutines.

Adds a regression test that fails without the fix.

Fixes #9567
2026-07-02 11:15:18 +01:00
maximilizeandNick Craig-Wood 294e985e2e filter: support nested {} alternates in glob filters - fixes #7220 2026-07-01 10:26:24 +01:00
Hakan İSMAİLandGitHub b36b679202 rc: allow setting rc config and filter options as flat parameters
This commit allows global config options to be set as flat parameters on all rc
commands. This makes the rc commands much more like command line parameters and
will aid understanding of how the rc is used.

It is backwards compatible with the old method using _config and _filter.
2026-06-30 17:04:33 +01:00
Nick Craig-Wood 105feca22b fs: fix command line flag being ignored when set to its default value
A backend flag set on the command line to a value that happened to
equal its default was silently ignored, letting the config file win
instead.

For example --sftp-user defaults to the current user, so connecting as
that same user with --sftp-user=USER had no effect and caused rclone
to use the value from the config file.

See: https://forum.rclone.org/t/sftp-user-parsing-as-cli-argument-broken/53955
2026-06-30 14:00:54 +01:00
user77andGitHub 0d3c9e929b fs/operations: correct DeleteFile --backup-dir documentation
DeleteFile always passes a nil backupDir to DeleteFileWithBackupDir, so
it never honours --backup-dir. The previous comment said it would move
the file into the backup dir when --backup-dir was in effect, which does
not match the code. Update the comment to state that DeleteFile always
deletes and that callers should use DeleteFileWithBackupDir when
--backup-dir support is required.

Also document on DeleteFileWithBackupDir that the backupDir is found with
BackupDir, which is relatively expensive, so it should be looked up once
outside any delete loop rather than per object.

#7566
2026-06-30 12:29:19 +01:00
Nick Craig-Wood 9ab8e4724a filter: fix --files-from copy stopping at the first unreadable file
Before this change, with --files-from and --no-traverse, a single file
that could not be read (for example permission denied) stopped all the
other files in the list being copied.

This happened because the error was returned from the listing, which
caused the whole source listing to be discarded.

This change counts and logs such per-file errors and carries on, so the
readable files are still copied and rclone exits with a non-zero error
code.

Fixes #9115
2026-06-25 10:21:07 +01:00
yashanil98andGitHub c7c6646ea3 config: fix root-relative markdown links in interactive config help - fixes #8239
Option help strings are also used to generate the website documentation,
so some contain markdown links with root-relative targets such as
[encoding section in the overview](/overview/#encoding). These render
correctly on rclone.org but are confusing in the interactive config
prompt, where the user sees the raw markdown and the link has no
reachable root.

Rewrite such links to text (https://rclone.org/path) when showing an
option's help in the interactive config. The raw help is left unchanged
so documentation generation is unaffected.
2026-06-25 10:20:14 +01:00
Yuhang Caoandalbertony 710514afb3 fs/hash: fix xxh128 hasher size 2026-06-15 08:14:03 +02:00
Nick Craig-Wood 16091ce365 fshttp: add --dump trace to log connection level events via httptrace
The new "trace" dump flag attaches a net/http/httptrace ClientTrace to
each HTTP transaction and logs the connection level events - DNS
resolution, TCP connect, TLS handshake (including the negotiated TLS
version, cipher, ALPN protocol and server certificate), connection
reuse, request write and time to first response byte. Each line is
tagged with the time elapsed since the start of the transaction and the
request pointer so it can be correlated with the other dumps.

This is complementary to the existing dump flags: it shows how the
connection behaved rather than what was sent, which is useful for
debugging connectivity, DNS, TLS, proxy and keep-alive problems.
2026-06-11 21:29:45 +01:00
Nick Craig-Wood 875a666f9c fshttp: add --dump errors to dump only failed HTTP transactions - fixes #9471
The new "errors" dump flag makes the HTTP dump conditional on the
transaction failing with a retryable error (a transport error, HTTP 429
or HTTP 5xx), so first-failure diagnostics can be captured without the
noise of dumping every transaction. The existing dump flags continue to
control what is dumped, for example --dump errors,bodies, and on its own
--dump errors dumps the headers.
2026-06-11 21:29:20 +01:00