duplicati/duplicati · error · Exception

Get failed

Error message

Get failed

What it means

Thrown by AliyunOSSBackend.GetAsync when the Aliyun OSS BeginGetObject/EndGetObject call returns an HTTP status other than 200 OK. The download is rejected at the API level; the exception is then logged via Logging.Log and re-thrown unchanged.

Source

Thrown at Duplicati/Library/Backend/AliyunOSS/AliyunOSSBackend.cs:235

        }

        public async Task GetAsync(string remotename, Stream stream, CancellationToken cancelToken)
        {
            var bucketName = _ossOptions.BucketName;
            var objectName = $"{_ossOptions.Path.TrimPath()}/{remotename}".TrimPath();
            var client = GetClient(false);

            try
            {
                var obj = await Utility.Utility.WithTimeout(_timeouts.ShortTimeout, cancelToken, async ct
                    => await Task.Factory.FromAsync(
                        (cb, state) => client.BeginGetObject(bucketName, objectName, null, null),
                        client.EndGetObject,
                        null).ConfigureAwait(false)
                    ).ConfigureAwait(false);

                if (obj.HttpStatusCode != HttpStatusCode.OK)
                    throw new Exception("Get failed");

                using (var requestStream = obj.Content)
                using (var timeoutStream = stream.ObserveWriteTimeout(_timeouts.ReadWriteTimeout, false))
                    await Utility.Utility.CopyStreamAsync(requestStream, timeoutStream, cancelToken).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Logging.Log.WriteErrorMessage(LOGTAG, "Get", ex, "Get failed: {0}", ex.Message);
                throw;
            }
        }

        public async Task RenameAsync(string oldname, string newname, CancellationToken cancelToken)
        {
            var bucketName = _ossOptions.BucketName;

            var sourceBucket = bucketName;

View on GitHub (pinned to 3f348be3e3)

Solutions

  1. Confirm the remote object name exists in the bucket (list the folder/path prefix).
  2. Verify the configured path prefix and credentials are correct for the bucket.
  3. If the object is archived (e.g. IA/Archive class), restore it in OSS before attempting a read.
  4. Check the OSS response status/error code in the server log to distinguish 404 from 403.
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    await backend.GetAsync(remotename, stream, cancelToken);
}
catch (Exception ex) when (ex.Message == "Get failed")
{
    // Non-200; commonly 404 (missing) or 403 (auth). List the prefix to distinguish.
    Log.Error("OSS get rejected (non-200) for {Name}; check existence and credentials", remotename);
    throw;
}

Prevention

When it happens

Trigger: GetAsync awaits the FromAsync get and checks obj.HttpStatusCode != OK, throwing before copying the stream. Non-200 occurs when the object does not exist (404), credentials are invalid, or the path is wrong. The outer catch logs 'Get failed' and re-throws the original exception.

Common situations: Requested remote file does not exist in the bucket; wrong path prefix configured; expired credentials returning 403; object in a different storage class requiring restore before read.

Related errors


AI-assisted analysis of duplicati/duplicati@3f348be3e3 (2026-08-13). Data as JSON: /api/errors/e6b5358a4ca39f85. Report an issue: GitHub.