diff --git a/changelog/unreleased/issue-4970 b/changelog/unreleased/issue-4970 new file mode 100644 index 000000000..524e91b75 --- /dev/null +++ b/changelog/unreleased/issue-4970 @@ -0,0 +1,13 @@ +Enhancement: Make timeout for stuck requests customizable + +Restic monitors connections to the backend to detect stuck requests. If a request +does not return any data within five minutes, restic assumes the request is stuck and +retries it. However, for large repositories it sometimes takes longer than that to +collect a list of all files, causing the following error: + +`List(data) returned error, retrying after 1s: [...]: request timeout` + +It is now possible to increase the timeout using the `--stuck-request-timeout` option. + +https://github.com/restic/restic/issues/4970 +https://github.com/restic/restic/pull/5014 diff --git a/cmd/restic/global.go b/cmd/restic/global.go index 22aa8a290..375b57f98 100644 --- a/cmd/restic/global.go +++ b/cmd/restic/global.go @@ -140,6 +140,7 @@ func init() { f.UintVar(&globalOptions.PackSize, "pack-size", 0, "set target pack `size` in MiB, created pack files may be larger (default: $RESTIC_PACK_SIZE)") f.StringSliceVarP(&globalOptions.Options, "option", "o", []string{}, "set extended option (`key=value`, can be specified multiple times)") f.StringVar(&globalOptions.HTTPUserAgent, "http-user-agent", "", "set a http user agent for outgoing http requests") + f.DurationVar(&globalOptions.StuckRequestTimeout, "stuck-request-timeout", 5*time.Minute, "`duration` after which to retry stuck requests") // Use our "generate" command instead of the cobra provided "completion" command cmdRoot.CompletionOptions.DisableDefaultCmd = true diff --git a/doc/faq.rst b/doc/faq.rst index b26398f8c..74dd77d71 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -228,3 +228,17 @@ Restic backup command fails to find a valid file in Windows If the name of a file in Windows contains an invalid character, Restic will not be able to read the file. To solve this issue, consider renaming the particular file. + +What can I do in case of "request timeout" errors? +-------------------------------------------------- + +Restic monitors connections to the backend to detect stuck requests. If a request +does not return any data within five minutes, restic assumes the request is stuck and +retries it. However, for large repositories it sometimes takes longer than that to +collect a list of all files, causing the following error: + +:: + + List(data) returned error, retrying after 1s: [...]: request timeout + +In this case you can increase the timeout using the ``--stuck-request-timeout`` option. diff --git a/internal/backend/http_transport.go b/internal/backend/http_transport.go index 5162d3571..5a3856e41 100644 --- a/internal/backend/http_transport.go +++ b/internal/backend/http_transport.go @@ -31,6 +31,9 @@ type TransportOptions struct { // Specify Custom User-Agent for the http Client HTTPUserAgent string + + // Timeout after which to retry stuck requests + StuckRequestTimeout time.Duration } // readPEMCertKey reads a file and returns the PEM encoded certificate and key @@ -143,7 +146,11 @@ func Transport(opts TransportOptions) (http.RoundTripper, error) { } if feature.Flag.Enabled(feature.BackendErrorRedesign) { - rt = newWatchdogRoundtripper(rt, 5*time.Minute, 128*1024) + if opts.StuckRequestTimeout == 0 { + opts.StuckRequestTimeout = 5 * time.Minute + } + + rt = newWatchdogRoundtripper(rt, opts.StuckRequestTimeout, 128*1024) } // wrap in the debug round tripper (if active)