function listLifecycleNonCurrents(authInfo, locationConstraints, request, log, callback) {
    const params = request.query;
    const bucketName = request.bucketName;

    log.debug('processing request', { method: 'listLifecycleNonCurrents' });
    const requestMaxKeys = params['max-keys'] ?
        Number.parseInt(params['max-keys'], 10) : 1000;
    if (Number.isNaN(requestMaxKeys) || requestMaxKeys < 0) {
        monitoring.promMetrics(
            'GET', bucketName, 400, 'listLifecycleNonCurrents');
        return callback(errors.InvalidArgument);
    }
    const actualMaxKeys = Math.min(constants.listingHardLimit, requestMaxKeys);

    // 3 is required as a minimum because we must scan at least three entries to determine version eligibility.
    // Two entries representing the master key and the following one representing the non-current version.
    const minEntriesToBeScanned = 3;
    const { isValid, maxScannedLifecycleListingEntries } =
        validateMaxScannedEntries(params, config, minEntriesToBeScanned);
    if (!isValid) {
        monitoring.promMetrics('GET', bucketName, 400, 'listLifecycleNonCurrents');
        return callback(errors.InvalidArgument);
    }

    const excludedDataStoreName = params['excluded-data-store-name'];
    if (excludedDataStoreName && !locationConstraints[excludedDataStoreName]) {
        const errMsg = getLocationConstraintErrorMessage(excludedDataStoreName);
        log.error(`locationConstraint is invalid - ${errMsg}`, { locationConstraint: excludedDataStoreName });
        monitoring.promMetrics('GET', bucketName, 400, 'listLifecycleCurrents');

        return callback(errorInstances.InvalidLocationConstraint.customizeDescription(errMsg));
    }

    const metadataValParams = {
        authInfo,
        bucketName,
        requestType: 'listLifecycleNonCurrents',
        request,
    };
    const listParams = {
        listingType: 'DelimiterNonCurrent',
        maxKeys: actualMaxKeys,
        prefix: params.prefix,
        beforeDate: params['before-date'],
        keyMarker: params['key-marker'],
        excludedDataStoreName,
        maxScannedLifecycleListingEntries,
    };

    listParams.versionIdMarker = params['version-id-marker'] ?
        versionIdUtils.decode(params['version-id-marker']) : undefined;

    return standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => {
        if (err) {
            log.debug('error processing request', { method: 'metadataValidateBucket', error: err });
            monitoring.promMetrics(
                'GET', bucketName, err.code, 'listLifecycleNonCurrents');
            return callback(err, null);
        }

        const vcfg = bucket.getVersioningConfiguration();
        const isBucketVersioned = vcfg && (vcfg.Status === 'Enabled' || vcfg.Status === 'Suspended');
        if (!isBucketVersioned) {
            log.debug('bucket is not versioned');
            return callback(errorInstances.InvalidRequest.customizeDescription(
                'bucket is not versioned'), null);
        }

        if (!requestMaxKeys) {
            const emptyList = {
                Contents: [],
                IsTruncated: false,
            };
            return handleResult(listParams, requestMaxKeys, authInfo,
                bucketName, emptyList, log, callback);
        }

        return services.getLifecycleListing(bucketName, listParams, log,
        (err, list) => {
            if (err) {
                log.debug('error processing request', { method: 'services.getLifecycleListing', error: err });
                monitoring.promMetrics(
                    'GET', bucketName, err.code, 'listLifecycleNonCurrents');
                return callback(err, null);
            }
            return handleResult(listParams, requestMaxKeys, authInfo,
                bucketName, list, log, callback);
        });
    });
}
listLifecycleNonCurrents - Return list of non-current versions in bucket
@param {AuthInfo} authInfo           - Instance of AuthInfo class with
                                        requester's info
@param {array} locationConstraints    - array of location contraint
@param {object} request              - http request object
@param {function} log                - Werelogs request logger
@param {function} callback           - callback to respond to http request
                                         with either error code or xml response body
@return {undefined}